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("加密解密异常");
    }
}

}

相关文章
|
3天前
|
算法 安全 Go
Go 语言中实现 RSA 加解密、签名验证算法
随着互联网的发展,安全需求日益增长。非对称加密算法RSA成为密码学中的重要代表。本文介绍如何使用Go语言和[forgoer/openssl](https://github.com/forgoer/openssl)库简化RSA加解密操作,包括秘钥生成、加解密及签名验证。该库还支持AES、DES等常用算法,安装简便,代码示例清晰易懂。
29 16
|
4月前
|
安全 算法 网络安全
浅谈非对称加密(RSA)
浅谈非对称加密(RSA)
174 0
|
3月前
|
存储 Java 数据库
密码专辑:对密码加盐加密,对密码进行md5加密,封装成密码工具类
这篇文章介绍了如何在Java中通过加盐和加密算法(如MD5和SHA)安全地存储密码,并提供了一个密码工具类PasswordUtils和密码编码类PasswordEncoder的实现示例。
93 10
密码专辑:对密码加盐加密,对密码进行md5加密,封装成密码工具类
|
3月前
|
算法 安全 Go
RSA加密算法详解与Python和Go实现
RSA加密算法详解与Python和Go实现
205 1
|
3月前
|
数据安全/隐私保护
sm4加密工具类
sm4加密工具类
49 3
|
3月前
|
算法 安全 网络安全
使用 Python 实现 RSA 加密
使用 Python 实现 RSA 加密
123 2
|
4月前
|
算法 安全 网络安全
概念区分:对称加密、非对称加密、公钥、私钥、签名、证书
概念区分:对称加密、非对称加密、公钥、私钥、签名、证书
180 0
|
4月前
|
安全 算法 数据安全/隐私保护
黑客克星!Python加密艺术大公开,AES、RSA双剑合璧,守护你的数字世界
在这个数据泛滥的时代,数字世界既充满了知识,也潜藏安全隐患。Python 作为强大的编程语言,以其独特的加密技术为我们的信息安全保驾护航。本文将介绍 AES 和 RSA 这两种加密算法,揭示它们如何协同工作,保护你的数字世界。AES(高级加密标准)以其高效、安全著称,能将敏感信息转化为难以破解的乱码。Python 的 `pycryptodome` 库让 AES 加密变得简单易行。然而,AES 面临密钥分发难题,此时 RSA(非对称加密算法)便大显身手,通过公钥加密、私钥解密的方式确保密钥传输安全。AES 与 RSA 在 Python 中交织成一道坚不可摧的防护网,共同守护我们的数字世界。
91 0
|
8天前
|
安全 算法 网络协议
【网络原理】——图解HTTPS如何加密(通俗简单易懂)
HTTPS加密过程,明文,密文,密钥,对称加密,非对称加密,公钥和私钥,证书加密
|
28天前
|
存储 SQL 安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将介绍网络安全的重要性,分析常见的网络安全漏洞及其危害,探讨加密技术在保障网络安全中的作用,并强调提高安全意识的必要性。通过本文的学习,读者将了解网络安全的基本概念和应对策略,提升个人和组织的网络安全防护能力。