Java生成RSA公钥、私钥 与 GO、PHP互相加密解密

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));

?>
上一篇:【无标题】


下一篇:CPP实现单链表(无类)