前情提要:架构中有两个系统,一个JAVA,一个PYTHON,之间的数据传输需要进行加密解密。 于是做了一个统一的工具。两系统之间可以相互加解密。
目录
一、JAVA
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
import cn.hutool.json.JSONObject;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Security;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
/**
* RSA加密解密工具类
*
* @author sunziwen
*/
public class RSAKeyGenerator {
static {
Security.addProvider(new BouncyCastleProvider());
}
/**
* 获取公钥私钥
*
* @return
* @throws NoSuchAlgorithmException
* @throws IOException
*/
public static Map<String, String> generateRSAKeyPair() throws NoSuchAlgorithmException, IOException {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(2048, new SecureRandom());
KeyPair keyPair = keyPairGen.generateKeyPair();
StringWriter publicKeyWriter = new StringWriter();
StringWriter privateKeyWriter = new StringWriter();
PemWriter pemWriter = new PemWriter(privateKeyWriter);
pemWriter.writeObject(new PemObject("PRIVATE KEY", keyPair.getPrivate().getEncoded()));
pemWriter.close();
pemWriter = new PemWriter(publicKeyWriter);
pemWriter.writeObject(new PemObject("PUBLIC KEY", keyPair.getPublic().getEncoded()));
pemWriter.close();
return new HashMap<String, String>() {{
put("PUBLIC_KEY", publicKeyWriter.toString());
put("PRIVATE_KEY", privateKeyWriter.toString());
}};
}
/**
* 公钥加密
*
* @param data 数据
* @param publicKeyPEM 公钥字符串
* @return
* @throws Exception
*/
public static String encryptWithPublicKey(String data, String publicKeyPEM) throws Exception {
// Convert PEM to PublicKey
String publicKeyPem = publicKeyPEM
.replaceAll("-----BEGIN PUBLIC KEY-----", "")
.replaceAll("-----END PUBLIC KEY-----", "")
.replaceAll("\r\n", "")
.replaceAll("\n", "");
byte[] encodedPublicKey = java.util.Base64.getDecoder().decode(publicKeyPem);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedPublicKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
// Encrypt
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
return java.util.Base64.getEncoder().encodeToString(encryptedData);
}
/**
* 私钥解密
*
* @param encryptedData 加密数据
* @param privateKeyPEM 私钥字符串
* @return
* @throws Exception
*/
public static String decryptWithPrivateKey(String encryptedData, String privateKeyPEM) throws Exception {
// Convert PEM to PrivateKey
String privateKeyPem = privateKeyPEM
.replaceAll("-----BEGIN PRIVATE KEY-----", "")
.replaceAll("-----END PRIVATE KEY-----", "")
.replaceAll("\r\n", "")
.replaceAll("\n", "");
byte[] encodedPrivateKey = java.util.Base64.getDecoder().decode(privateKeyPem);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
// Decrypt
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedData = cipher.doFinal(java.util.Base64.getDecoder().decode(encryptedData));
return new String(decryptedData, StandardCharsets.UTF_8);
}
public static void main(String[] args) throws Exception {
// 数据
JSONObject jsonObject = new JSONObject();
jsonObject.set("username", "詹姆斯");
jsonObject.set("company", "凯尔特人");
String jsonString = jsonObject.toString();
Map<String, String> rsaKeyPair = generateRSAKeyPair();
String public_key = rsaKeyPair.get("PUBLIC_KEY");
String private_key = rsaKeyPair.get("PRIVATE_KEY");
System.out.println("公钥: " + public_key);
System.out.println("私钥: " + private_key);
// 加密
String encryptedData = encryptWithPublicKey(jsonString, public_key);
System.out.println("加密数据: " + encryptedData);
// 解密
String decryptedData = decryptWithPrivateKey(encryptedData, private_key);
System.out.println("解密数据: " + decryptedData);
}
}
二、PYTHON
pip install cryptography
import base64
import json
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
def generate_rsa_key_pair():
"""
获取公钥私钥
:return:
"""
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
)
public_key = private_key.public_key()
pem_private_key = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
)
pem_public_key = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
print("公钥:", pem_public_key.decode(encoding="utf-8"))
print("私钥:", pem_private_key.decode(encoding="utf-8"))
return pem_public_key.decode(encoding="utf-8"), pem_private_key.decode(encoding="utf-8")
def encrypt_with_public_key(data, public_key):
"""
公钥加密
:param data: 数据
:param public_key: 公钥字符串
:return:
"""
public_key = serialization.load_pem_public_key(public_key.encode(encoding="utf-8"))
encrypted_data = public_key.encrypt(
data.encode(encoding="utf-8"),
padding.PKCS1v15()
)
return base64.b64encode(encrypted_data).decode(encoding="utf-8")
def decrypt_with_private_key(encrypted_data, private_key):
"""
私钥解密
:param encrypted_data: 加密数据
:param private_key: 私钥字符串
:return:
"""
private_key = serialization.load_pem_private_key(private_key.encode(encoding="utf-8"), password=None,
backend=serialization.NoEncryption())
decrypted_data = private_key.decrypt(
base64.b64decode(encrypted_data),
padding.PKCS1v15()
)
return decrypted_data.decode(encoding="utf-8")
if __name__ == '__main__':
data = {"username": "詹姆斯", "company": "凯尔特人"}
# 获取公钥私钥
public_key, private_key, = generate_rsa_key_pair()
# 公钥加密
encrypt_data = encrypt_with_public_key(json.dumps(data), public_key)
print("加密数据:", encrypt_data)
# 私钥解密
decrypt_data = decrypt_with_private_key(encrypt_data, private_key)
print(json.loads(decrypt_data))