Java生成RSA公钥、私钥 与 GO、PHP互相加密解密
一,Java生成公钥、私钥
//作者:贤冰
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class RsaUtil {
public static void main(String[] args) throws Exception {
try {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(512, new SecureRandom());
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
//公钥
String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
//私钥
String privateKeyString = new String(Base64.encodeBase64(privateKey.getEncoded()));
System.out.println("公钥: " + publicKeyString);
System.out.println("私钥: " + privateKeyString);
String encrypted = publicKeyEncrypt("hello world", publicKeyString);
System.out.println(encrypted);
System.out.println(privateKeyDecrypt(encrypted,privateKeyString));
System.out.println();
} catch (NoSuchAlgorithmException e) {
System.out.println(e.getMessage());
}
}
//公钥加密
public static String publicKeyEncrypt(String data, String publicKeyString) throws Exception {
byte[] decoded = Base64.decodeBase64(publicKeyString);
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE,pubKey);
return Base64.encodeBase64String(cipher.doFinal(data.getBytes(StandardCharsets.UTF_8)));
}
//私钥解密
public static String privateKeyDecrypt(String encrypted, String privateKeyString) throws Exception {
byte[] inputByte = Base64.decodeBase64(encrypted.getBytes(StandardCharsets.UTF_8));
byte[] decodedPrivKey = Base64.decodeBase64(privateKeyString);
RSAPrivateKey privKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decodedPrivKey));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE,privKey);
return new String(cipher.doFinal(inputByte));
}
}
生成密钥
公钥普通模式: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOSLZ6k5g5GevISr6mh3/vpXuJVD/XabavEu+AXQCBciQnGD9bShBrh4ePU2jrvbIkjtQfxZDSLdrzgyojl1YsECAwEAAQ==
私钥普通模式: MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEA5ItnqTmDkZ68hKvqaHf++le4lUP9dptq8S74BdAIFyJCcYP1tKEGuHh49TaOu9siSO1B/FkNIt2vODKiOXViwQIDAQABAkEAjulRT/OD/0oojjnGYb8vdTHnXYdfdoxnChwZweC9PmDiSym33IZT7glhDTwp4WEiBUaBsl3EElXEKz/mWRm8ZQIhAPnK7xGsSPYIGSBn5H6r6n5e+MC2P40It5aSW10JcnCrAiEA6jlM0KdMf+EyCygYmp58T1eaEfzoxDKmVwJuNTiBskMCIQDcVm51R2SAaXpIhHwgZGMPH5UK4HfEXwkaL3WZ5qhkywIgX+J3NM/YPF2nS/PtJpcM0rpNA2Iis/b8K5B+J2FrjtsCIAN8l/r4p6/u1utyl4G5+878L54iKdWvDJdK8MsXQYxM
Java公钥加密
public static String publicKeyEncrypt(String data, String publicKeyString) throws Exception {
byte[] decoded = Base64.decodeBase64(publicKeyString);
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE,pubKey);
return Base64.encodeBase64String(cipher.doFinal(data.getBytes(StandardCharsets.UTF_8)));
}
Java私钥解密
//私钥解密
public static String privateKeyDecrypt(String encrypted, String privateKeyString) throws Exception {
byte[] inputByte = Base64.decodeBase64(encrypted.getBytes(StandardCharsets.UTF_8));
byte[] decodedPrivKey = Base64.decodeBase64(privateKeyString);
RSAPrivateKey privKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decodedPrivKey));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE,privKey);
return new String(cipher.doFinal(inputByte));
}
Java生成的密钥,在Go和PHP中使用时,需要补上Pem格式的前缀和后缀
#公钥格式
"-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----"
#私钥格式
"-----BEGIN PRIVATE KEY-----\n%s\n-----END PRIVATE KEY-----"
二,GO使用Java生成的RSA密钥对 进行加密、解密
//作者:贤冰
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"errors"
"fmt"
)
type RsaCrypto struct {
publicKey []byte
privateKey []byte
}
func NewRsa(pubKey, privKey string) *RsaCrypto {
return &RsaCrypto{
publicKey: []byte(fmt.Sprintf("-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----", pubKey)),
privateKey: []byte(fmt.Sprintf("-----BEGIN PRIVATE KEY-----\n%s\n-----END PRIVATE KEY-----", privKey)),
}
}
// 公钥加密
func (rc *RsaCrypto) PublicKeyEncrypt(data []byte) ([]byte, error) {
block, _ := pem.Decode(rc.publicKey)
if block == nil {
return nil, errors.New("public key error")
}
pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
pub := pubInterface.(*rsa.PublicKey)
return rsa.EncryptPKCS1v15(rand.Reader, pub, data)
}
// 私钥解密
func (rc *RsaCrypto) PrivateKeyDecrypt(encrypted []byte) ([]byte, error) {
block, _ := pem.Decode(rc.privateKey)
if block == nil {
return nil, errors.New("private key error!")
}
privInterface, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
priv := privInterface.(*rsa.PrivateKey)
return rsa.DecryptPKCS1v15(rand.Reader, priv, encrypted)
}
func main() {
javaPublic := "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOSLZ6k5g5GevISr6mh3/vpXuJVD/XabavEu+AXQCBciQnGD9bShBrh4ePU2jrvbIkjtQfxZDSLdrzgyojl1YsECAwEAAQ=="
javaPrivate := "MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEA5ItnqTmDkZ68hKvqaHf++le4lUP9dptq8S74BdAIFyJCcYP1tKEGuHh49TaOu9siSO1B/FkNIt2vODKiOXViwQIDAQABAkEAjulRT/OD/0oojjnGYb8vdTHnXYdfdoxnChwZweC9PmDiSym33IZT7glhDTwp4WEiBUaBsl3EElXEKz/mWRm8ZQIhAPnK7xGsSPYIGSBn5H6r6n5e+MC2P40It5aSW10JcnCrAiEA6jlM0KdMf+EyCygYmp58T1eaEfzoxDKmVwJuNTiBskMCIQDcVm51R2SAaXpIhHwgZGMPH5UK4HfEXwkaL3WZ5qhkywIgX+J3NM/YPF2nS/PtJpcM0rpNA2Iis/b8K5B+J2FrjtsCIAN8l/r4p6/u1utyl4G5+878L54iKdWvDJdK8MsXQYxM"
data := "hello rsa"
rsaCrypto := NewRsa(javaPublic, javaPrivate)
encrypted, err := rsaCrypto.PublicKeyEncrypt([]byte(data))
if err != nil {
panic(err)
}
fmt.Println("公钥加密:", base64.StdEncoding.EncodeToString(encrypted))
decrypted, err := rsaCrypto.PrivateKeyDecrypt(encrypted)
if err != nil {
panic(err)
}
fmt.Println("私钥解密:", string(decrypted))
}
三,PHP使用Java生成的RSA密钥对 进行加密、解密
<?php
//作者:贤冰
class RsaCrypto {
private static $_instance = null;
protected $publicKey = '';
protected $privateKey = '';
public function __construct($pubKey, $privKey) {
$this->publicKey = $pubKey;
$this->privateKey = $privKey;
}
public static function getInstance($pubKey, $privKey) {
if(self::$_instance!=null){
return self::$_instance;
}
self::$_instance = new self($pubKey, $privKey);
return self::$_instance;
}
public static function formatPublicKey($pubKey) : string {
return sprintf("-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----",$pubKey);
}
public static function formatPrivateKey($privKey) : string {
return sprintf("-----BEGIN PRIVATE KEY-----\n%s\n-----END PRIVATE KEY-----",$privKey);
}
//公钥加密
public function publicKeyEncrypt($data) : string {
if(openssl_public_encrypt($data, $encrypted, $this->publicKey)){
return base64_encode($encrypted);
}
return "";
}
//私钥解密
public function privateKeyDecrypt($encrypted) : string {
if(openssl_private_decrypt(base64_decode($encrypted), $decrypted, $this->privateKey)){
return $decrypted;
}
return "";
}
}
$javaPublic = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOSLZ6k5g5GevISr6mh3/vpXuJVD/XabavEu+AXQCBciQnGD9bShBrh4ePU2jrvbIkjtQfxZDSLdrzgyojl1YsECAwEAAQ==';
$javaPrivate = 'MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEA5ItnqTmDkZ68hKvqaHf++le4lUP9dptq8S74BdAIFyJCcYP1tKEGuHh49TaOu9siSO1B/FkNIt2vODKiOXViwQIDAQABAkEAjulRT/OD/0oojjnGYb8vdTHnXYdfdoxnChwZweC9PmDiSym33IZT7glhDTwp4WEiBUaBsl3EElXEKz/mWRm8ZQIhAPnK7xGsSPYIGSBn5H6r6n5e+MC2P40It5aSW10JcnCrAiEA6jlM0KdMf+EyCygYmp58T1eaEfzoxDKmVwJuNTiBskMCIQDcVm51R2SAaXpIhHwgZGMPH5UK4HfEXwkaL3WZ5qhkywIgX+J3NM/YPF2nS/PtJpcM0rpNA2Iis/b8K5B+J2FrjtsCIAN8l/r4p6/u1utyl4G5+878L54iKdWvDJdK8MsXQYxM';
$data = 'hello rsa';
$rsaCrypto = RsaCrypto::getInstance(RsaCrypto::formatPublicKey($javaPublic),RsaCrypto::formatPrivateKey($javaPrivate));
//公钥加密
$encrypted = $rsaCrypto->publicKeyEncrypt($data);
echo sprintf("加密后: %s\n",$encrypted);
//私钥解密
echo sprintf("解密后: %s\n",$rsaCrypto->privateKeyDecrypt($encrypted));
?>