RSA算法加密/解密和签名/验签工具类

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: RSA算法加密/解密和签名/验签工具类

public class RsaUtils {

/**
 * 算法名称
 */
private static final String ALGORITHM = "RSA";
/**
 * 签名算法 MD5withRSA 或 SHA1WithRSA 等
 */
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
/**
 * 密钥长度默认是1024位:
 * 加密的明文最大长度 = 密钥长度 - 11(单位是字节,即byte)
 */
private static final int KEY_SIZE = 1024;
/**
 * RSA最大加密明文大小
 */
private static final int MAX_ENCRYPT_BLOCK = 117;

/**
 * RSA最大解密密文大小
 */
private static final int MAX_DECRYPT_BLOCK = 128;


/**
 * 获取密钥对
 *
 * @return 密钥对
 */
public static KeyPair getKeyPair() throws Exception {
    KeyPairGenerator generator = KeyPairGenerator.getInstance(ALGORITHM);
    generator.initialize(KEY_SIZE);
    return generator.generateKeyPair();
}

/**
 * 私钥字符串转PrivateKey实例
 *
 * @param privateKey 私钥字符串
 * @return
 */
public static PrivateKey getPrivateKey(String privateKey) throws Exception {
    KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
    byte[] decodedKey = Base64.getDecoder().decode(privateKey.getBytes("UTF-8"));// 对私钥进行Base64编码解密
    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
    return keyFactory.generatePrivate(keySpec);
}

/**
 * 公钥字符串转PublicKey实例
 *
 * @param publicKey 公钥字符串
 * @return
 */
public static PublicKey getPublicKey(String publicKey) throws Exception {
    KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
    byte[] decodedKey = Base64.getDecoder().decode(publicKey.getBytes("UTF-8")); // 对公钥进行Base64编码解密
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);
    return keyFactory.generatePublic(keySpec);
}

/**
 * 公钥加密
 *
 * @param data      待加密数据
 * @param publicKey 公钥
 * @return
 */
public static String encryptByPublicKey(String data, PublicKey publicKey) {
    try (
            ByteArrayOutputStream out = new ByteArrayOutputStream();
    ) {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        int inputLen = data.getBytes("UTF-8").length;
        int offset = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段加密
        while (inputLen - offset > 0) {
            if (inputLen - offset > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(data.getBytes("UTF-8"), offset, MAX_ENCRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data.getBytes("UTF-8"), offset, inputLen - offset);
            }
            out.write(cache, 0, cache.length);
            i++;
            offset = i * MAX_ENCRYPT_BLOCK;
        }
        byte[] encryptedData = out.toByteArray();
        // 获取加密内容使用Base64进行编码加密,并以UTF-8为标准转化成字符串
        // 加密后的字符串
        //return new String(Base64.encodeBase64String(encryptedData));
        return new String(Base64.getEncoder().encode(encryptedData), "UTF-8");
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

/**
 * 私钥解密
 *
 * @param data       待解密数据
 * @param privateKey 私钥
 * @return
 */
public static String decryptByPrivateKey(String data, PrivateKey privateKey) {
    try (
            ByteArrayOutputStream out = new ByteArrayOutputStream();
    ) {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        // 对待解密数据进行Base64编码解密
        byte[] dataBytes = Base64.getDecoder().decode(data.getBytes("UTF-8"));
        int inputLen = dataBytes.length;
        int offset = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段解密
        while (inputLen - offset > 0) {
            if (inputLen - offset > MAX_DECRYPT_BLOCK) {
                cache = cipher.doFinal(dataBytes, offset, MAX_DECRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(dataBytes, offset, inputLen - offset);
            }
            out.write(cache, 0, cache.length);
            i++;
            offset = i * MAX_DECRYPT_BLOCK;
        }
        byte[] decryptedData = out.toByteArray();
        // 解密后的内容
        return new String(decryptedData, "UTF-8");
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

/**
 * 私钥签名
 *
 * @param data       待签名数据
 * @param privateKey 私钥
 * @return 签名
 */
public static String sign(String data, PrivateKey privateKey) throws Exception {
    byte[] keyBytes = privateKey.getEncoded();
    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
    PrivateKey key = keyFactory.generatePrivate(keySpec);
    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    signature.initSign(key);
    signature.update(data.getBytes());
    return new String(Base64.getEncoder().encode(signature.sign()));  // 对签名内容进行Base64编码加密
}

/**
 * 公钥验签
 *
 * @param srcData   原始字符串
 * @param publicKey 公钥
 * @param sign      签名
 * @return 是否验签通过
 */
public static boolean verify(byte[] srcData, PublicKey publicKey, String sign) throws Exception {
    byte[] keyBytes = publicKey.getEncoded();
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
    PublicKey key = keyFactory.generatePublic(keySpec);
    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    signature.initVerify(key);
    signature.update(srcData);
    return signature.verify(Base64.getDecoder().decode(sign));
}

public static void main(String[] args) {
    try {
        // 生成密钥对
        KeyPair keyPair = getKeyPair();
        String privateKey = new String(Base64.getEncoder().encode(keyPair.getPrivate().getEncoded()), "UTF-8");
        String publicKey = new String(Base64.getEncoder().encode(keyPair.getPublic().getEncoded()), "UTF-8");
        System.out.println("私钥:" + privateKey);
        System.out.println("公钥:" + publicKey);
        // RSA加密
        String data = "签名算法可以是NIST标准DSA,使用DSA和SHA-1。 使用SHA-1消息摘要算法的DSA算法可以指定为SHA1withDSA 。 在RSA的情况下,\n" +
                "存在对消息多个选择摘要算法,所以签名算法可被指定为,例如, MD2withRSA , MD5withRSA ,或SHA1withRSA 。 必须指定算法名称,因为没有默认值。";
        String encryptData = encryptByPublicKey(data, getPublicKey(publicKey));
        System.out.println("加密后内容:" + encryptData);
        // RSA解密
        String decryptData = decryptByPrivateKey(encryptData, getPrivateKey(privateKey));
        System.out.println("解密后内容:" + decryptData);

        // RSA签名
        String sign = sign(data, getPrivateKey(privateKey));
        System.out.println("签名内容:" + sign);
        // RSA验签
        boolean result = verify(data.getBytes(), getPublicKey(publicKey), sign);
        System.out.print("验签结果:" + result);

    } catch (Exception e) {
        e.printStackTrace();
        System.out.print("加密解密异常");
    }
}

}

相关文章
|
5天前
|
算法 安全 Go
Go 语言中实现 RSA 加解密、签名验证算法
随着互联网的发展,安全需求日益增长。非对称加密算法RSA成为密码学中的重要代表。本文介绍如何使用Go语言和[forgoer/openssl](https://github.com/forgoer/openssl)库简化RSA加解密操作,包括秘钥生成、加解密及签名验证。该库还支持AES、DES等常用算法,安装简便,代码示例清晰易懂。
32 12
|
3月前
|
存储 Java 数据库
密码专辑:对密码加盐加密,对密码进行md5加密,封装成密码工具类
这篇文章介绍了如何在Java中通过加盐和加密算法(如MD5和SHA)安全地存储密码,并提供了一个密码工具类PasswordUtils和密码编码类PasswordEncoder的实现示例。
93 10
密码专辑:对密码加盐加密,对密码进行md5加密,封装成密码工具类
|
3月前
|
算法 搜索推荐 Java
java 后端 使用 Graphics2D 制作海报,画echarts图,带工具类,各种细节:如头像切割成圆形,文字换行算法(完美实验success),解决画上文字、图片后不清晰问题
这篇文章介绍了如何使用Java后端技术,结合Graphics2D和Echarts等工具,生成包含个性化信息和图表的海报,并提供了详细的代码实现和GitHub项目链接。
161 0
java 后端 使用 Graphics2D 制作海报,画echarts图,带工具类,各种细节:如头像切割成圆形,文字换行算法(完美实验success),解决画上文字、图片后不清晰问题
|
3月前
|
算法 安全 Go
RSA加密算法详解与Python和Go实现
RSA加密算法详解与Python和Go实现
209 1
|
3月前
|
数据安全/隐私保护
sm4加密工具类
sm4加密工具类
49 3
|
5月前
|
算法 安全 数据安全/隐私保护
Android经典实战之常见的移动端加密算法和用kotlin进行AES-256加密和解密
本文介绍了移动端开发中常用的数据加密算法,包括对称加密(如 AES 和 DES)、非对称加密(如 RSA)、散列算法(如 SHA-256 和 MD5)及消息认证码(如 HMAC)。重点讲解了如何使用 Kotlin 实现 AES-256 的加密和解密,并提供了详细的代码示例。通过生成密钥、加密和解密数据等步骤,展示了如何在 Kotlin 项目中实现数据的安全加密。
187 1
|
5月前
|
算法 安全 数据安全/隐私保护
Android经典实战之常见的移动端加密算法和用kotlin进行AES-256加密和解密
本文介绍了移动端开发中常用的数据加密算法,包括对称加密(如 AES 和 DES)、非对称加密(如 RSA)、散列算法(如 SHA-256 和 MD5)及消息认证码(如 HMAC)。重点展示了如何使用 Kotlin 实现 AES-256 的加密和解密,提供了详细的代码示例。
103 2
|
5月前
|
算法 JavaScript 前端开发
国标非对称加密:RSA算法、非对称特征、js还原、jsencrypt和rsa模块解析
国标非对称加密:RSA算法、非对称特征、js还原、jsencrypt和rsa模块解析
355 1
|
11天前
|
机器学习/深度学习 算法
基于改进遗传优化的BP神经网络金融序列预测算法matlab仿真
本项目基于改进遗传优化的BP神经网络进行金融序列预测,使用MATLAB2022A实现。通过对比BP神经网络、遗传优化BP神经网络及改进遗传优化BP神经网络,展示了三者的误差和预测曲线差异。核心程序结合遗传算法(GA)与BP神经网络,利用GA优化BP网络的初始权重和阈值,提高预测精度。GA通过选择、交叉、变异操作迭代优化,防止局部收敛,增强模型对金融市场复杂性和不确定性的适应能力。
145 80
|
4天前
|
机器学习/深度学习 算法
基于遗传优化的双BP神经网络金融序列预测算法matlab仿真
本项目基于遗传优化的双BP神经网络实现金融序列预测,使用MATLAB2022A进行仿真。算法通过两个初始学习率不同的BP神经网络(e1, e2)协同工作,结合遗传算法优化,提高预测精度。实验展示了三个算法的误差对比结果,验证了该方法的有效性。