RSA加密Java与Python通用版

前情提要:架构中有两个系统,一个JAVA,一个PYTHON,之间的数据传输需要进行加密解密。 于是做了一个统一的工具。两系统之间可以相互加解密。


目录

一、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))

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
RSA是一种非对称加密算法,可以用于加密和解密数据。PythonJava都支持RSA加密,但是它们的实现略有不同。 在Python中,可以使用Crypto库来实现RSA加密。以下是一个使用Python进行RSA加密的示例: ```python from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP # generate RSA key pair key = RSA.generate(2048) # get public key public_key = key.publickey() # encrypt message using public key message = b'Hello World' cipher = PKCS1_OAEP.new(public_key) encrypted_message = cipher.encrypt(message) print(encrypted_message) ``` 在Java中,可以使用Java Cryptography Architecture(JCA)提供的API来实现RSA加密。以下是一个使用Java进行RSA加密的示例: ```java import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import javax.crypto.Cipher; public class Main { public static void main(String[] args) throws Exception { // generate RSA key pair KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(2048); KeyPair keyPair = keyPairGenerator.generateKeyPair(); // get public and private key PublicKey publicKey = keyPair.getPublic(); PrivateKey privateKey = keyPair.getPrivate(); // encrypt message using public key String message = "Hello World"; Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] encryptedMessage = cipher.doFinal(message.getBytes()); System.out.println(new String(encryptedMessage)); } } ``` 需要注意的是,在使用RSA加密时,要确保加密的数据不超过密钥长度减去11个字节,否则会抛出异常。因此,在实际应用中,可以使用对称加密算法来加密长数据,然后使用RSA加密对称加密算法的密钥。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

文子阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值