<h1>RSA</h1>
<h2>RSA加密</h2>
在RSA中,明文、密钥和密文都是数字。加密过程可以用下列公式:
<span class="img-wrap"></span>
加密公式中出现的<code>E</code>和<code>N</code>的组合就是公钥。
<h2>RSA解密</h2>
公式:
<span class="img-wrap"></span>
数字<code>D</code>和<code>N</code>组合起来就是RSA的私钥。
<h2>生成密钥对</h2>
<ol><li>求N</li></ol>
<code>N = p x q</code> (p、q为质数)。q、q太小容易被破译,太大会导致计算时间很长。
<code>N = 17 x 19 = 323</code>
<ol><li>求L(L是仅在生成密钥对的过程中使用的数)</li></ol>
<code>L = lcm(p-1,q-1)</code> (L是p-1和q-1的最小公倍数)
<code>L = lcm(16,18) = 144</code>
<ol><li>求E</li></ol>
<code>1 < E < L</code>
<code>gcd(E,L) = 1</code> ;表示E和L的最大公约数为1;
<code>E = 5,7,11,13,17,19,23,25,29,31</code>
<ol><li>求D</li></ol>
<code>1 < D < L</code>
<code>E x D mod L = 1</code>
<code>D = 29</code>
<h2>代码1</h2>
<pre><code>package main
import (
"encoding/pem"
"crypto/x509"
"crypto/rsa"
"crypto/rand"
"fmt"
)
//RSA对称性加密
//公钥加密、私钥解密
var priKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCe8zGb4UAMg2A63pH /W145hHvYQPJlkX6OfzJ1215htCI6Pyh
2TdHRrDqVU6wP609ao9tLxRsbbXrajBGXiq2ijRX7AKrsVdhYi2J B2q/CrsH5CD
Ka16YCVPPwf/oZDz/hxrcjZjhOoSIZupY3/xzOBTTjcVcvWbTxGw0wOm6wIDAQAB
AoGABrVg7KFPILgSwalPJCHyEt4y95VyoXl0LqFv59ztw lKt9yNfQ875Ag5w0oi
bhHh7 ulbghEpmbi/LKYov qccTQMCz4PW1g85LrUYI5PaGKQfsTAWldQeV/mxCk
mimCk8bahoWPX4i2fnyFdCCn7f3kL8RqRp4NXu2En2gJkPECQQDL3QZrRBpxuE8L
vgMPNew II3XtiMzsXc/EwHpAT2hY/pOXt0pvtGfAU2d1JSzmHlBfqPkhr2S0obE
PpdsXyG3AkEAx5mt8rsDflY8vRYU7Xao0 Smt 9ujMhvtzzS9W62VCUU8xc0UG x
umgxofSOedkoaR7k2jqFYYbC1CrwPyAUbQJBALle2R9gZctSFE5REOcb2R0E7PVg
oNG4ZP3tgqckga3nAwuQJvp2kJVM0g7Z5f0If/mV9eEuw JlnDWF1JquRjECQQCi
ZrT0eRsnkO0MgEn4yAInnbPUlphhLbhP48pVbYYmQqGgBHJJPAfkfmBbwMqn83uA
xGU59kGOD4K39FPTWLulAkAngU3Yv8vYmZKcYXuc/TZjxa0sMuRVroWO6ciW81so
sFpf0SM9Ysgf/nKtux7juJABCfF1ffDQdKwederSMOc
-----END RSA PRIVATE KEY-----`)
//声明公钥
//公钥可以公开给所有人使用,可以用作加密,可以用作验签
var pubKey = []byte(`-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCe8zGb4UAMg2A63pH /W145hHv
YQPJlkX6OfzJ1215htCI6Pyh2TdHRrDqVU6wP609ao9tLxRsbbXrajBGXiq2ijRX
7AKrsVdhYi2J B2q/CrsH5CDKa16YCVPPwf/oZDz/hxrcjZjhOoSIZupY3/xzOBT
TjcVcvWbTxGw0wOm6wIDAQAB
-----END PUBLIC KEY-----`)
//RSA加密算法
func RSAEncrypt(origData []byte) []byte {
//通过公钥加密
block,_:=pem.Decode(pubKey)
//解析公钥
pubInterface,_:=x509.ParsePKIXPublicKey(block.Bytes)
//加载公钥
pub:=pubInterface.(*rsa.PublicKey)
//利用公钥pub加密
bits,_:=rsa.EncryptPKCS1v15(rand.Reader,pub,origData)
//返回密文
return bits
}
//RSA解密
func RSADecrypt(cipherTxt []byte) []byte {
//通过私钥解密
block,_:=pem.Decode(priKey)
//解析私钥
pri,_:=x509.ParsePKCS1PrivateKey(block.Bytes)
//解密
bits,_:=rsa.DecryptPKCS1v15(rand.Reader,pri,cipherTxt)
//返回明文
return bits
}
func main() {
//加密
cipher:=RSAEncrypt([]byte("hello zhaoyingkui "))
fmt.Println(cipher)
//解密
plain:=RSADecrypt(cipher)
fmt.Println(string(plain))
}</code></pre>
<h2>代码2</h2>
<pre><code>package main
import (
"crypto/rsa"
"crypto/rand"
"fmt"
"crypto/md5"
"encoding/base64"
"crypto"
)
//用公钥加密,私钥解密
//用私钥签名,公钥验证
//公钥是公开的,任何人可以使用公钥,私钥非公开(保存好)
//一,编程实现,公钥加密,私钥解密的过程
func crypt() {
//创建私钥
priv, _ := rsa.GenerateKey(rand.Reader, 1024)
fmt.Println("输出系统自动产生的私钥", priv)
//创建公钥
pub := priv.PublicKey
//准备加密的明文
org := []byte("hello kongyixueyuan")
//公钥加密
cipherTxt, _ := rsa.EncryptOAEP(md5.New(), rand.Reader, &pub, org, nil)
//打印密文
fmt.Println("密文为:", cipherTxt)
fmt.Println("密文为:", base64.StdEncoding.EncodeToString(cipherTxt))
//用私钥解密
plaintext, _ := rsa.DecryptOAEP(md5.New(), rand.Reader, priv, cipherTxt, nil)
//打印解密后的结果
fmt.Println("明文为:", string(plaintext))
}
func main() {
crypt()
}
</code></pre>
<h1>椭圆曲线</h1>
<h2>go生成钱包应用</h2>
<pre><code>package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"log"
"fmt"
"crypto/sha256"
"golang.org/x/crypto/ripemd160"
"bytes"
"encoding/base64"
)
type Wallet struct {
//1.私钥
PrivateKey ecdsa.PrivateKey
//2.公钥
PublicKey [] byte
}
func NewWallet() *Wallet {
privateKey, publicKey := newKeyPair()
//fmt.Println("privateKey:", privateKey, ",publicKey:", publicKey)
fmt.Println("公钥为:", base64.StdEncoding.EncodeToString(publicKey))
fmt.Println("私钥为:", privateKey)
return &Wallet{privateKey, publicKey}
}
//通过私钥产生公钥
func newKeyPair() (ecdsa.PrivateKey, []byte) {
/*
elliptic:椭圆
curve:曲线
ecdsa:elliptic curve digital signature algorithm,椭圆曲线数字签名算法
比特币使用SECP256K1算法,p256是ecdsa算法中的一种
ecc:椭圆曲线加密
dsa:
*/
//椭圆加密
curve := elliptic.P256() //椭圆加密算法,得到一个椭圆曲线值,全称:SECP256k1
private, err := ecdsa.GenerateKey(curve, rand.Reader)
//fmt.Println("--------私钥:", private)
//fmt.Printf("%T\n", private)
if err != nil {
log.Panic(err)
}
//公钥,就是
pubKey := append(private.PublicKey.X.Bytes(), private.PublicKey.Y.Bytes()...)
return *private, pubKey
}
/*
两次sha256,1次160
然后version hash
*/
func (w *Wallet) GetAddress() [] byte {
//1.先将公钥进行一次hash256
ripemd160Hash := w.Ripemd160Hash(w.PublicKey)
version_ripemd160Hash := append([]byte{version}, ripemd160Hash...)
checkSumBytes := CheckSum(version_ripemd160Hash)
bytes := append(version_ripemd160Hash, checkSumBytes...)
return Base58Encode(bytes)
}
func (w *Wallet) Ripemd160Hash(publicKey [] byte) []byte {
//1.256
hash256 := sha256.New()
hash256.Write(publicKey)
hash := hash256.Sum(nil)
//2.160
ripemd := ripemd160.New()
ripemd.Write(hash)
return ripemd.Sum(nil)
}
const version = byte(0x00)
const addressChecksumLen = 4
func CheckSum(b [] byte) []byte {
//2次256hash
hash1 := sha256.Sum256(b)
hash2 := sha256.Sum256(hash1[:])
return hash2[:addressChecksumLen]
}
//判断地址是否有效
func IsValidForAddress(address []byte) bool {
version_public_checksumBytes := Base58Decode(address)
fmt.Println("检验version_public_checksumBytes:", version_public_checksumBytes)
checkSumBytes := version_public_checksumBytes[len(version_public_checksumBytes)-addressChecksumLen:]
fmt.Println("检验checkSumBytes:", checkSumBytes)
version_ripemd160 := version_public_checksumBytes[:len(version_public_checksumBytes)-addressChecksumLen]
fmt.Println("检验version_ripemd160:", version_ripemd160)
checkBytes := CheckSum(version_ripemd160)
fmt.Println("检验checkBytes:", checkBytes)
if bytes.Compare(checkSumBytes, checkBytes) == 0 {
return true
}
return false
}
func Base58Encode(address []byte) []byte {
// 未实现功能,后续补上
return address
}
func Base58Decode(address []byte) []byte {
// 未实现功能,后续补上
return address
}
func main(){
NewWallet()
}
</code></pre>
<h1>其他应用</h1>
<h2>公钥生成地址</h2>
在上述的代码中有体现。
<span class="img-wrap"></span>
<h2>openssl</h2>
<pre><code>//生成私钥
openssl genrsa -out rsa_private_key.pem 1024
//将私钥做pkcs8的转码
openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM
//通过私钥生成公钥
openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout</code></pre>
<blockquote class="layui-elem-quote" style="width: 100%;overflow:hidden">
作者: 未知
链接: https://segmentfault.com/a/1190000016667117
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
</blockquote>
到此这篇关于“【go密码学】-非对称加密算法”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!
您可能感兴趣的文章:
密码学之对称加密
【go密码学】-非对称加密算法
PHP 数据加密的方法
有关discuz程序中PHP加密函数的原理分析
PHP中的加密功能
Python:常见的加密方式
Go从入门到精通系列视频之go编程语言密码学哈希算法
golang基础学习-AES加密
C#做的一个加密/解密的类
asp.net实现RSA加密