介绍
前几天在工作中遇到Golang与Java的Rsa密钥加密解密互相不通,其原因之一就是密钥的版本问题,比如Go生成的密钥是PKCS1的,而Java使用的是PKCS8,这时候就需要通过工具去转换下,我推荐在线转地址:ssleye.com/ssltool/pkcs.html。注意,只有私钥需要转,公钥不需要!
生成密钥
另外,密钥的生成最好用openssl工具去生成一个,一般git软件里面也有,可以直接用,目录:git\usr\bin
# 生成私钥
.\openssl.exe genrsa -out private_key.pem 2048
# 根据私钥生成公钥
.\openssl.exe rsa -in private_key.pem -pubout -out rsa_public_key.pem
Java代码
/**
* Go语言的RSA密钥要和Java交互,需要先将私钥的格式从PKCS1转换成PKCS8,公钥不需要转换
*/
public class RSAEncrypt {
// 都是原生的密钥(加密转了)
private static final String USER_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCRUnsc/N3lCehibQxqHCR3SfPE" +
"...这里替换你自己的私钥..." +
"BNJk7sNOl5zPmu1hhQIDAQAB";
// pcks8密钥
private static final String USER_PRIVATE_KEY =
"MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJFSexz83eUJ6GJt" +
"...这里替换你自己的私钥..." +
"+rsZpZP8XwBYiw==";
public static void main(String[] args) throws Exception {
String aaa = userEncrypt("aaa");
System.out.println("密文:" + aaa);
String content = userDecrypt("X+uOtdCM5b15CH9hnRSamCpobRyMt31FHBW5pon4EHHq2CPcnHaQ50sof9gzsucf +qIP4a2rhBK2QdMSMusYXfAIFE1lrLRqDGM5MpO2IDNEGw9SmxfyIHS9eUIxnApVwKm5WiXiBB81sYwqA9ebU1HVDYL/jGdueOdbq0d1ZFQ=");
System.out.println("解密:" + content);
}
public static String userDecrypt(String str) throws Exception {
//64位解码加密后的字符串
byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
//base64编码的私钥
byte[] decoded = Base64.decodeBase64(USER_PRIVATE_KEY);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
return new String(cipher.doFinal(inputByte));
}
public static String userEncrypt(String str) throws Exception {
//base64编码的公钥
byte[] decoded = Base64.decodeBase64(USER_PUBLIC_KEY);
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
//RSA加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
return Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
}
}
Go代码
文件名:JavaRSA_test.go
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"testing"
)
// go 语言支持原生的密钥 java 需要转成pkcs8 才能用
var privateKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCRUnsc/N3lCehibQxqHCR3SfPE35GDYl0XAY0zHsmnwBkumgrz
...替换成你自己的私钥...
mKD6+Nkf/n4iTqW1ZCEcNkrOvMZHH/q7GaWT/F8AWIs=
-----END RSA PRIVATE KEY-----`)
var publicKey = []byte(`-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCRUnsc/N3lCehibQxqHCR3SfPE
...替换成你自己的公钥...
-----END PUBLIC KEY-----`)
func TestSin(t *testing.T) {
cipherText := RSAEncrypt("aa")
fmt.Println("密文:", cipherText)
content := RSADecrypt(cipherText)
fmt.Println("解密:" + content)
}
// 加密
func RSAEncrypt(origData string) string {
block, _ := pem.Decode(publicKey)
if block == nil {
return "public key error"
}
pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return "public key error"
}
pub := pubInterface.(*rsa.PublicKey)
aimByte, _ := rsa.EncryptPKCS1v15(rand.Reader, pub, []byte(origData))
str := base64.StdEncoding.EncodeToString(aimByte)
return str
}
// 解密
func RSADecrypt(ciphertext string) string {
block, _ := pem.Decode(privateKey)
if block == nil {
return "private key error!"
}
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return "private key error!"
}
// base 64 解密
sDec, _ := base64.StdEncoding.DecodeString(ciphertext)
bb, _ := rsa.DecryptPKCS1v15(rand.Reader, priv, sDec)
return string(bb)
}