在go语言中RSA包函数的示例代码
最实用、最流行的密码学系统之一是RSA。加密的工作方式是允许公共/加密钥匙......公开,而私人/解密钥匙则保持私密。你可以看到RSA常用于电子邮件和安全外壳登录。
RSA是Ron Rivest、Adi Shamir和Leonard Adleman的缩写,他们在1977年首次公开描述了该算法。
在这个例子中,我们将向你展示如何使用crypto/rsa包中列出的每个函数。
代码示例:
package main
import (
"crypto"
"crypto/md5"
"crypto/rand"
"crypto/rsa"
"fmt"
"io"
"os"
)
func main() {
// generate private key
privatekey, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
fmt.Println(err.Error)
os.Exit(1)
}
D := privatekey.D //private exponent
Primes := privatekey.Primes
PCValues := privatekey.Precomputed
// Note : Only used for 3rd and subsequent primes
//CRTVal := privatekey.Precomputed.CRTValues
fmt.Println("Private Key : ", privatekey)
fmt.Println()
fmt.Println("Private Exponent : ", D.String())
fmt.Println()
fmt.Printf("Primes : %s %s \n", Primes[0].String(), Primes[1].String())
fmt.Println()
fmt.Printf("Precomputed Values : Dp[%s] Dq[%s]\n", PCValues.Dp.String(), PCValues.Dq.String())
fmt.Println()
fmt.Printf("Precomputed Values : Qinv[%s]", PCValues.Qinv.String())
fmt.Println()
// Note : Only used for 3rd and subsequent primes
//fmt.Printf("CRTValues : Exp[%s]\n Coeff[%s]\n R[%s]\n", CRTVal[2].Exp.String(), CRTVal[2].Coeff.String(), CRTVal[2].R.String())
// Note : if you want to have multi primes,
// use rsa.GenerateMultiPrimeKey() function instead of
// rsa.GenerateKey() function
// see http://golang.org/pkg/crypto/rsa/#GenerateMultiPrimeKey
// http://golang.org/pkg/crypto/rsa/#PrivateKey.Precompute
privatekey.Precompute()
// http://golang.org/pkg/crypto/rsa/#PrivateKey.Validate
err = privatekey.Validate()
if err != nil {
fmt.Println(err.Error)
os.Exit(1)
}
var publickey *rsa.PublicKey
publickey = &privatekey.PublicKey
N := publickey.N // modulus
E := publickey.E // public exponent
fmt.Println("Public key ", publickey)
fmt.Println()
fmt.Println("Public Exponent : ", E)
fmt.Println()
fmt.Println("Modulus : ", N.String())
fmt.Println()
// EncryptOAEP
msg := []byte("The secret message!")
label := []byte("")
md5hash := md5.New()
encryptedmsg, err := rsa.EncryptOAEP(md5hash, rand.Reader, publickey, msg, label)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Printf("OAEP encrypted [%s] to \n[%x]\n", string(msg), encryptedmsg)
fmt.Println()
// DecryptOAEP
decryptedmsg, err := rsa.DecryptOAEP(md5hash, rand.Reader, privatekey, encryptedmsg, label)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Printf("OAEP decrypted [%x] to \n[%s]\n", encryptedmsg, decryptedmsg)
fmt.Println()
// EncryptPKCS1v15
encryptedPKCS1v15, errPKCS1v15 := rsa.EncryptPKCS1v15(rand.Reader, publickey, msg)
if errPKCS1v15 != nil {
fmt.Println(errPKCS1v15)
os.Exit(1)
}
fmt.Printf("PKCS1v15 encrypted [%s] to \n[%x]\n", string(msg), encryptedPKCS1v15)
fmt.Println()
// DecryptPKCS1v15
decryptedPKCS1v15, err := rsa.DecryptPKCS1v15(rand.Reader, privatekey, encryptedPKCS1v15)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Printf("PKCS1v15 decrypted [%x] to \n[%s]\n", encryptedPKCS1v15, decryptedPKCS1v15)
fmt.Println()
// SignPKCS1v15
var h crypto.Hash
message := []byte("This is the message to be signed!")
hash := md5.New()
io.WriteString(hash, string(message))
hashed := hash.Sum(nil)
signature, err := rsa.SignPKCS1v15(rand.Reader, privatekey, h, hashed)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Printf("PKCS1v15 Signature : %x\n", signature)
//VerifyPKCS1v15
err = rsa.VerifyPKCS1v15(publickey, h, hashed, signature)
if err != nil {
fmt.Println("VerifyPKCS1v15 failed")
os.Exit(1)
} else {
fmt.Println("VerifyPKCS1v15 successful")
}
fmt.Println()
// SignPSS
var opts rsa.PSSOptions
opts.SaltLength = rsa.PSSSaltLengthAuto // for simple example
PSSmessage := []byte("Message to be PSSed!")
newhash := crypto.MD5
pssh := newhash.New()
pssh.Write(PSSmessage)
hashed = pssh.Sum(nil)
signaturePSS, err := rsa.SignPSS(rand.Reader, privatekey, newhash, hashed, &opts)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Printf("PSS Signature : %x\n", signaturePSS)
//VerifyPSS
err = rsa.VerifyPSS(publickey, newhash, hashed, signaturePSS, &opts)
if err != nil {
fmt.Println("VerifyPSS failed")
os.Exit(1)
} else {
fmt.Println("VerifyPSS successful")
}
}
输出:
go run rsa.go
Private Key : &{{14069868.....1134595521000335073 []}}
Private Exponent : 5992956235453428....7114123469729744785553
Primes : 1068234819....6154480540983
Precomputed Values : Dp[394485849....817550064792145] Dq[7908872...711190209031]
Precomputed Values : Qinv[10207476873..0335073]
Public key &{1406986827....23117039 65537}
Public Exponent : 65537
Modulus : 140698682716428....100805145523117039
OAEP encrypted [The secret message!] to [97052db00....05dffbe51]
OAEP decrypted [97052db0010.....605dffbe51] to [The secret message!]
PKCS1v15 encrypted [The secret message!] to [c029be25bd15a1bfa6.....c3cb617f92fd94]
PKCS1v15 decrypted [c029be25bd15a...b617f92fd94] to [The secret message!]
PKCS1v15 Signature : 53968867c6b26f3...de16194fb5e VerifyPKCS1v15 successful
PSS Signature : 8a49cb40a22....dc8ed91acd12aa VerifyPSS successful
这个例子的简单性是为了更容易理解如何使用这些函数。
对于这些函数的更高级实现,请参见
https://code.google.com/p/go/source/browse/src/pkg/crypto/rsa/
参考资料:
http://golang.org/pkg/crypto/rsa/
相关文章