RSA加密算法 RSA加密算法 RSA之go与Java 加解密算法对应关系 签名算法对应关系 密钥系列化与反序列化 生成密钥对 密钥序列化为字符串(pkcs1标准不推荐再使用,而且Java标准库也不提供支持) 密钥反序列化为密钥对象 留一个示例(Go与Java交互)
RSA加密算法
RSA之go与Java
加解密算法对应关系
Go Java EncryptPKCS1v15 RSA/ECB/PKCS1Padding(加密模式) DecryptPKCS1v15 RSA/ECB/PKCS1Padding(解密模式) EncryptOAEP(可以指定具体的hash算法) RSA/ECB/OAEPWithSHA-1AndMGF1Padding (go的sha1算法 )(加密模式)RSA/ECB/OAEPWithSHA-256AndMGF1Padding (go的sha256算法 )(加密模式)DecryptOAEP(可以指定具体的hash算法) RSA/ECB/OAEPWithSHA-1AndMGF1Padding (go的sha1算法 )(解密模式)RSA/ECB/OAEPWithSHA-256AndMGF1Padding (go的sha256算法 )(解密模式)
签名算法对应关系
Go Java rsa.SignPKCS1v15(指定不同的hash算法,对应Java算法名称前面的SHA名称 ) SHA1withRSA、SHA256withRSA、SHA384withRSA、SHA512withRSA(对应sign方法) rsa.VerifyPKCS1v15(指定不同的hash算法,对应Java算法名称前面的SHA名称 ) SHA1withRSA、SHA256withRSA、SHA384withRSA、SHA512withRSA(对应sign方法) rsa.SignPSS()(同样指定不同的hash算法 ) RSASSA-PSS (配合PSSParameterSpec(指定具体的hash算法 ) 使用)sign 方法rsa.VerifyPSS(同样指定不同的 hash算法 ) RSASSA-PSS(配合PSSParameterSpec(指定具体的hash算法) 使用)verify 方法
密钥系列化与反序列化
Go Java x509.MarshalPKCS1PrivateKey 标准库不支持 PKCS#1 x509.MarshalPKCS1PublicKey 标准库不支持 PKCS#1 x509.ParsePKCS1PrivateKey 标准库不支持 PKCS#1 x509.ParsePKCS1PublicKey 标准库不支持 PKCS#1 x509.MarshalPKCS8PrivateKey PrivateKey#getEncoded x509.MarshalPKIXPublicKey PublicKey.getEncoded() x509.ParsePKCS8PrivateKey PKCS8EncodedKeySpec x509.ParsePKIXPublicKey X509EncodedKeySpec
生成密钥对
go中生成密钥对非常简单
key, err := rsa. GenerateKey ( rand. Reader, 1024 )
publicKey := key. PublicKey
密钥序列化为字符串(pkcs1标准不推荐再使用,而且Java标准库也不提供支持)
java需借助 Bouncy Castle 等第三方库解析PKCS1的密钥。大致代码如下
RSAPrivateKeyStructure keyStructure = new RSAPrivateKeyStructure ( ( ASN1Sequence ) ASN1Sequence . fromByteArray ( Base64 . getDecoder ( ) . decode ( base64PrivateKey) ) ) ;
RSAPrivateKeySpec privateKeySpec = new RSAPrivateKeySpec ( keyStructure. getModulus ( ) , keyStructure. getPrivateExponent ( ) ) ;
KeyFactory keyFactory = KeyFactory . getInstance ( "RSA" ) ;
PrivateKey privateKey = keyFactory. generatePrivate ( privateKeySpec) ;
key, _ := rsa. GenerateKey ( rand. Reader, 1024 )
privateByte := x509. MarshalPKCS1PrivateKey ( key)
publicByte := x509. MarshalPKCS1PublicKey ( & key. PublicKey)
privateByteBase64 := base64. StdEncoding. EncodeToString ( privateByte)
publicByteBase64 := base64. StdEncoding. EncodeToString ( publicByte) p ( "私钥:" , privateByteBase64)
p ( "公钥:" , publicByteBase64)
密钥反序列化为密钥对象
privateKeyDec, _ := base64. StdEncoding. DecodeString ( privateByteBase64)
privateKey, _ := x509. ParsePKCS1PrivateKey ( privateKeyDec)
publicKeyDec, _ := base64. StdEncoding. DecodeString ( publicByteBase64)
publicKey, _ := x509. ParsePKCS1PublicKey ( publicKeyDec)
留一个示例(Go与Java交互)
Go(加密、签名)
privateKey, err := rsa. GenerateKey ( rand. Reader, 2048 ) if err != nil { fmt. Println ( "生成私钥失败:" , err) return } publicKey := privateKey. PublicKeyplaintext := [ ] byte ( "这是一段要加密的文字" ) encryptedData, err := rsa. EncryptPKCS1v15 ( rand. Reader, & publicKey, plaintext) if err != nil { fmt. Println ( "加密失败:" , err) return } encryptedBase64 := base64. StdEncoding. EncodeToString ( encryptedData) fmt. Println ( "Base64编码后的密文:" , encryptedBase64) privateKeyBase64 := privateKeyToBase64 ( privateKey) fmt. Println ( "Base64编码后的私钥:" , privateKeyBase64) publicKeyBase64 := publicKeyToBase64 ( & publicKey) fmt. Println ( "Base64编码后的公钥:" , publicKeyBase64) hashed := sha256. Sum256 ( plaintext) sha256, err := rsa. SignPKCS1v15 ( rand. Reader, privateKey, crypto. SHA256, hashed[ : ] ) if err != nil { panic ( err) } p ( "签名:" , base64. StdEncoding. EncodeToString ( sha256) )
Java(解密、验签)
解密
String base64PrivateKey = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCmcxhZF3Q0TBMavmcUueq2BJ09QbXUM+rYrPbIXFN5wecrpGs1T+gaZ6HnKTkHLR55iBhVfJ6QTjRcdkREZ86EwkhlJItKp8P9HlR+cNdoDTXMLYKZmSrZ2o0gS5wjGd8f6bil+BauIac8uWOgXULIU8QnAAJECflvcAsJWIlhbTG3gaDSGlBODmViTMxe64WowEaLdo3MFUZhTF/i3Q+KhLan8l99pLrA5ufXx9pMrexMsbzuNW/9AKV4j++ANRuxIhMPY4UauFCOEgtbBx6BWKUXK9/eGO7LJSeOQoZBM2yDnsobVojCjSSQmuInue3PE0i7GcBlw0X+oOgpY/G/AgMBAAECggEBAIm09xPeP5l0xul9VTLkjbaBIsWnM5OYUFdq4dDp8XXuYh7NLJUywsf1rRDeHfw969SIL/mp3FVvHgrRHbGqYEWdpt9m2IavPYqQKT9ihBPlufhuPnptKfKKye9KHqc7pEl2x/knwzvVQ9MNXcsy3Sl3g/TwIO/BgMgdXkQhJ6edpY4+bag238UmVCqe2oRvpqiSN477afBsa1JNyfY1UEjku+wvj1wNJ56NPS3TAeq1B8XIBGB7IooVAXB4OU4k1zf1FvYeNguiMBOIUh/Gdl3Z+FXMt3hvI8yoNJre3KupmR8j3TzlgkhJgg53ZZTUfgjzy479DwUhYQYvqcICeMECgYEAxpGPldUHLP+1kxutnVHEDPCIF8bqndh3RMKLG0ggY62RDphCOfzzMnYLPjA9CgIdIPo9gPRKcMYsJ2rNJMaSX3LuA7po4BNlG7aMkQT5Ztaa1XtFg3GsS+UjYnbF6Aj1Gt+UUc7SdrJs/WrRzxMD2IGX34mkEjAdaQzudvsJ3JkCgYEA1pdf/2/OCLbj2qNM1dsnFEhfUFw+dmbnvRHl1H8+DDWKkiFZVGEwbdp2mtosvlw/dZXNdeW2VBULjCLBGkfgA5cxXUJomSjT5anfPD0LtJZJSvRlD7P9dAY59/5ySiCRi7/ko7ID6fWhJvpNj0sOMR1tafkoVTB9eX4OAHYeIBcCgYEAizLDSy+5BgyDxwpiHKSTINcFMFXbZqe2hFc0mP1o5zdnNqn50xjFi5xAqWm7gGaW8OU7dEjMXl4t2bv+70bcmVjCDY8BsgMmn9TKmWa5RyQuCnWN92UaeWG5+m50sgKFgD83hFnOJDNUQBo/1j/oNEA0rRmaEL32AAx2pqW49hECgYEAjm5c5mNkQn550AWxmwRh9OFwehsvzlDRIbo+bQOjwGDNP97otsvnZBKrxG5pYlRCPp6Wh9lXYomxZ2st9m6cbmWs+zR3zqi9tGNC622tVkimDx0V8w1JffggA82cOD1TvYk5jbk7Rc+mDgP29NQhcFIS7FLXBWww7DHRw1ai+jMCgYAglIzt0lUc6Yx5OUOtnm/3Tn1gH1NmktAXyC1JNQxxp9CBHDtD038LJHuArSyLp1hxRzoJ4E5cmUTWLLx4v5pMGunrcDPZrj/oJBfFDc5SItDZ6H2PKqrN0ZvyqxUxW6NIwhKpkjEif9SayrDZP5vHDbcVp8ScMJKwz7ynUkRCcg==" ;
String base64EncryptedText = "U2PeiPR52FVkDuBWdTcg0Cu0SAiVIQ0GuPh8TYivP91rGwIf/nRQsZ5pznEVX3YPypV0caJWInk6p6HEW3D4C1mGnrnG5BttDTKIFneyN8Yv46LOg83Tykk+1vY47+OflLBPYX4zIFSLBUyQMPJUaFWAYmQ3Zy/32Bm2i3gl/H9foeM4Mf+BBdrv2jRKdm738e5V6xvOhQbcW7K4eav0MhX+0PXJPSlwgXch7Fh1dRj50Gb2srVYgvg/pshHIHEZgkfsry60xmn9qBkqFIHybqlow0l5632TMU3qDnLTXt1Z1goos0/QSzIRlWkwDr9IRMfo1H9AFcajrNRP1aJIpw==" ;
PrivateKey privateKey = getPrivateKeyFromBase64 ( base64PrivateKey) ;
byte [ ] encryptedBytes = Base64 . getDecoder ( ) . decode ( base64EncryptedText) ;
byte [ ] decryptedBytes = decrypt ( privateKey, encryptedBytes) ;
System . out. println ( "解密后的文本: " + new String ( decryptedBytes) ) ;
public static PrivateKey getPrivateKeyFromBase64 ( String base64PrivateKey) throws NoSuchAlgorithmException , InvalidKeySpecException { byte [ ] privateKeyBytes = Base64 . getDecoder ( ) . decode ( base64PrivateKey) ; KeyFactory keyFactory = KeyFactory . getInstance ( "RSA" ) ; PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec ( privateKeyBytes) ; return keyFactory. generatePrivate ( keySpec) ; } public static byte [ ] decrypt ( PrivateKey privateKey, byte [ ] encryptedData) throws NoSuchPaddingException , java. security. InvalidKeyException, javax. crypto. IllegalBlockSizeException, javax. crypto. BadPaddingException, NoSuchAlgorithmException { Cipher cipher = Cipher . getInstance ( "RSA/ECB/PKCS1Padding" ) ; cipher. init ( Cipher . DECRYPT_MODE , privateKey) ; return cipher. doFinal ( encryptedData) ; }
验签
String publicStr = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwsTqgcW8vD+Ac9mnE1T2DDP7Nu2voifcC4xS60gvtC8cDKhqMP3B/Vno2InJ06EP94VZFukXZlbQaIF5U2z5Dyp/iT+yPjQnG6ZBL9IjrPovL1rvcUkDZu+yqajvKM0FCz+NsPIzO8pjlRGjIlfGKC9Of1XutxUwlux5aR55NA0vXCN60giz4DK2HFIKQioITwOduEeYL1xinUpY7lGLkouPJRjrVvvcjzgb5QCeLS5vxQ6EsmrzcomnAKfnGar1dvSVUqJk0lu9nrWygJngRsotLG4VbwRVTklWH49rEr5fkPtaal4avtjCiXXNalHscv/nU/fwF1okKCIt5hmV+QIDAQAB" ;
String sign = "RjYdalZyJpqOTjQwK1VJd2kD+5gHnTliqbhhpLfda7lq7BWlQ84VzRy+rs3W2yBI1aJtNKj8ByXwD9jJh51fmMunCPZ/Uv6tpuuSGGE0mAeIE3gl1aPSipjvKO7PBpYMsbFxI4NiL9Zh0LKLStUj4Xtc92pmXJdcL80JlTEdxC+vx7dsO/GXzM0TGskFD1whpYETLFEFc4ASD9AXMBNVycdv4jWFO/SRN+LUtpTQsSWC/K7o8wlXCqFE4zsOnj/fgG2uKwt7aZMyZN/hdLP3T+MftXaFeVFOphh/9E6SvOCqo7mP9MXu5SUBL2/pfDpV5fxeNzVW6I8VnfxMLgnHFA==" ;
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec ( Base64 . getDecoder ( ) . decode ( publicStr) ) ;
KeyFactory keyFactory = KeyFactory . getInstance ( "RSA" ) ;
PublicKey publicKey = keyFactory. generatePublic ( x509EncodedKeySpec) ; Signature signature = Signature . getInstance ( "SHA256withRSA" ) ;
signature. initVerify ( publicKey) ;
String plain = "这是一段要加密的文字" ;
byte [ ] bytes = plain. getBytes ( StandardCharsets . UTF_8 ) ;
signature. update ( bytes) ;
boolean verify = signature. verify ( Base64 . getDecoder ( ) . decode ( sign) ) ;
System . out. println ( "验签结果:" + verify) ;