golang和Java的RSA加解密互通

2 篇文章 0 订阅

介绍

前几天在工作中遇到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)
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值