【Java实现RSA的加密解密签名验签】


简介

  RSA(Rivest-Shamir-Adleman)是一种非对称加密算法,常用于加密和解密数据,数字签名和密钥交换。RSA算法的安全性基于两个关键的数学难题:大质数的素因子分解问题和指数对数问题。

  非对称加密: RSA是一种非对称加密算法,意味着它使用一对密钥,即公钥和私钥。公钥用于加密数据,私钥用于解密数据。这种非对称性使RSA非常适合数字通信的安全性,因为发送者只需知道接收者的公钥,而无需知道私钥。


一、依赖类和接口

import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;

import javax.crypto.Cipher;
import java.util.Base64;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

二、实例化入参

 // 密钥类实例化入参
private static final String KEY_ALGORITHM = "RSA";
private static final int KEY_SIZE = 2048;

 // Cipher类实例化入参
private static final String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding";

 // 签名类实例化入参
private static final String SIGNATURE_ALGORITHM = "SHA1withRSA";

三、生成公私钥对

/**
* 功能描述随机生成公私钥对
*/
public static KeyPair generateRSAKeyPair(int keySize) throws NoSuchAlgorithmException {
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
    keyPairGenerator.initialize(keySize);
    return keyPairGenerator.generateKeyPair();
}

四、加解密

/**
* 加密
*/
public static byte[] encryptWithRSA(byte[] data, PublicKey publicKey) throws Exception {
    Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    return cipher.doFinal(data);
}

/**
* 解密
*/
public static byte[] decryptWithRSA(byte[] encryptedData, PrivateKey privateKey) throws Exception {
    Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
    cipher.init(Cipher.DECRYPT_MODE, privateKey);
    return cipher.doFinal(encryptedData);
}

五、签名验签

/**
* 签名
*/
public static byte[] signWithRSA(byte[] data, PrivateKey privateKey) throws Exception {
    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    signature.initSign(privateKey);
    signature.update(data);
    return signature.sign();
}

/**
* 验签
*/
public static boolean verifyWithRSA(byte[] data, byte[] signatureBytes, PublicKey publicKey) throws Exception {
    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    signature.initVerify(publicKey);
    signature.update(data);
    return signature.verify(signatureBytes);
}

六、编码转换

/**
* 将DER编码的私钥字节数组转换为RSAPrivateKey对象
*/
public static RSAPrivateKey getRSAPrivateKeyFromEncoded(byte[] derEncodedPrivateKey) throws Exception {
    // Create KeyFactory for RSA
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

    // Convert DER-encoded private key to PrivateKey
    PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(derEncodedPrivateKey);
    RSAPrivateKey privateKey = (RSAPrivateKey)keyFactory.generatePrivate(privateKeySpec);

    return privateKey;
}

/**
* 将DER编码的公钥字节数组转换为RSAPublicKey对象
*/
public static RSAPublicKey getRSAPublicKeyFromEncoded(byte[] derEncodedPublicKey) throws Exception {
    // Create KeyFactory for RSA
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

    // Convert DER-encoded public key to PublicKey
    X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(derEncodedPublicKey);
    RSAPublicKey publicKey = (RSAPublicKey)keyFactory.generatePublic(publicKeySpec);

    return publicKey;
}

七、Bash64 转换

/**
* 使用Base64编码字节数组
*/
public static String encodeBase64(byte[] input) {
    byte[] encodedBytes = Base64.getEncoder().encode(input);
    return new String(encodedBytes);
}

/**
* 使用Base64解码字节数组
*/
public static byte[] decodeBase64(String input) {
    byte[] decodedBytes = Base64.getDecoder().decode(input);
    return decodedBytes;
}

八、测试代码

try {
    String teststring = "1234567890";

    // 生成公私钥
    KeyPair keypair = generateRSAKeyPair(KEY_SIZE );
    RSAPublicKey publicKey = (RSAPublicKey)keypair.getPublic();
    RSAPrivateKey privateKey = (RSAPrivateKey)keypair.getPrivate();

    byte[] en_data = encryptWithRSA(teststring.getBytes(), publicKey);
    byte[] de_data = decryptWithRSA(en_data , privateKey );
    System.out.println("de_data: " + de_data);

    byte[] sign_data = signWithRSA(teststring.getBytes(), privateKey);
    boolean verify_result = verifyWithRSA(teststring.getBytes(),sign_data, publicKey);
    System.out.println("verify_result:" + isLeapYear);
} catch (Exception e) {
    e.printStackTrace();
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

失控的程序猿

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

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

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

打赏作者

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

抵扣说明:

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

余额充值