您的位置 首页 php

RSA工具类:加解密和签名验签

rsa作为一种安全高效的非对称加密方法,经常在需要身份验证和加解密场景下使用。

由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全。

base64编码工具依赖jar

 <dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.60</version>
 </dependency>  

RSA加解密和签名验签的工具类

签名方法sign()和验证签名verify()方法是一对,配合使用。代码如下:

 public class RsaUtils {
    public static final String KEY_ALGORITHM = "RSA";
    public static final String UTF8 = "utf-8";

    /**
     * RSA最大加密明文大小
     */
    private static final int MAX_ENCRYPT_BLOCK = 117;

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

    /**
     * 私钥签名
     */
    public static String sign(String content, String privateKeyPem) {
        try {
            byte[] encodedKey = privateKeyPem.getBytes();
            encodedKey = Base64.decode(encodedKey);
            PrivateKey privateKey = KeyFactory.getInstance(KEY_ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
            Signature signature = Signature.getInstance("SHA256WithRSA");
            signature.initSign(privateKey);
            signature.update(content.getBytes(UTF8));
            byte[] signed = signature.sign();
            return new String(Base64.encode(signed));
        } catch (Exception ex) {
            String errorMessage = "RSA签名异常,content=" + content + " privateKeySize=" + privateKeyPem.length() + " reason=" + ex.getMessage();
            throw new RuntimeException(errorMessage, ex);
        }
    }

    /**
     * 公钥验签
     */
    public static boolean verify(String content, String sign, String publicKeyPem) {
        try {
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            byte[] encodedKey = publicKeyPem.getBytes();
            encodedKey = Base64.decode(encodedKey);
            PublicKey publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
            Signature signature = Signature.getInstance("SHA256WithRSA");
            signature.initVerify(publicKey);
            signature.update(content.getBytes(UTF8));
            return signature.verify(Base64.decode(sign.getBytes()));
        } catch (Exception ex) {
            String errorMessage = "RSA验签异常,content=" + content + " sign=" + sign + " publicKey=" + publicKeyPem + " reason=" + ex.getMessage();
            throw new RuntimeException(errorMessage, ex);
        }
    }

    /**
     * 私钥加密
     */
    public static String encryptByPrivateKey(String text, String privateKey) throws Exception {
        byte[] keyBytes = Base64.decode(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, privateK);
        byte[] data = text.getBytes(StandardCharsets.UTF_8);
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_ENCRYPT_BLOCK;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        byte[] base64Arr = Base64.encode(encryptedData);
        String base64 = new String(base64Arr, "utf-8");
        return base64;
    }

    /**
     * 公钥解密
     */
    public static String decryptByPublicKey(String base64Str, String publicKey)
            throws Exception {
        byte[] keyBytes = Base64.decode(publicKey);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key publicK = keyFactory.generatePublic(x509KeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, publicK);
        byte[] encryptedData = Base64.decode(base64Str);
        int inputLen = encryptedData.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段解密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_DECRYPT_BLOCK;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        String source = new String(decryptedData, "utf-8");
        return source;
    }
}  

如何使用?

测试代码如下:

 public class RsaUtilsTest{
    static String PRIVATE_KEY = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAND7PIe2no4HwLDeFq5muHjigwktYnXFPKSYHKbOgI/sONaqFojfqR5Aq6XdSRA6sj0gVsFTRI/xY96nWu5BiJ5iY9Y1RH83hd0uWnWEuWraJb1Q/D1haWmCRNDfcLEzHHlDbXQabP62fwfb6t7WJfC4NKvtzRXXVKYQ+zWQDqLNAgMBAAECgYAh+ebCbcdjchE68DCh1CODy9fgAxfx68pLPEvUNtiiDZbEF80oHaziNUNy6QI6+EAIPhy8u6v29xj0lyLqf48VXYdwYAS74pD9vTFk8Gl+Nd8tk6y63DP25ZGYGIov0jAJxjr1+8y/CrIa5jEotuzeKPe1z5w+7iAfasryGcITpQJBAP0kyrRVKG02ekWbzIrn6GVmD1Pq7QLkwzs7pTWI492sNtTLjxuR6TSlRCxe6EL3khgi8/ty8pVry2rHPNm4TO8CQQDTVuGdZ0fQj1ZEVGmlsSe/glqSpdsGx0Whh/D22tffTf+6j9JVNnWypP0HgWr678d0tHQvVFWbjOR6XtAdbgQDAkEA2qWSp9v+BQbO6Zy+OSRBqINUrej2Ok+ZCWplMi5AktESsw33V5rZ0O0GS0TWXDE18L8P+Zm5SbJHirz4JB155QJAVD8FDycVtKj+/ZwcxUU6kBgZnO3qwuf69Opo/y678TN5ptggQ4HDJ2SnzS8lA0VEYFxzGE7pFWnzxmg3VBQAGwJBAJiJDNsouSKPqxdOZhBLKPHPnce1/V8oXSvyeDc1J2jEzWIPsS0IvRokXA0ggq5UM5EcUb/q01/Uda6iv6O8umg=";
    static String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQ+zyHtp6OB8Cw3hauZrh44oMJLWJ1xTykmBymzoCP7DjWqhaI36keQKul3UkQOrI9IFbBU0SP8WPep1ruQYieYmPWNUR/N4XdLlp1hLlq2iW9UPw9YWlpgkTQ33CxMxx5Q210Gmz+tn8H2+re1iXwuDSr7c0V11SmEPs1kA6izQIDAQAB";

    public static void main(String[] args) throws Exception {
        String text = "hello world,good job.";
        String sign = RsaUtils.sign(text, PRIVATE_KEY);
        boolean verify = RsaUtils.verify(text, sign, PUBLIC_KEY);
        System.out.println("sign--verify = " + verify);

        final String rsaSign = RsaUtils.encryptByPrivateKey(text, PRIVATE_KEY);
        System.out.println("encrypt=" + rsaSign);
        String decSign = RsaUtils.decryptByPublicKey(rsaSign, PUBLIC_KEY);
        System.out.println("decrypt=" + decSign);
        System.out.println("encrypt--decrypt");
    }
}  

执行结果如下图:

文章来源:智云一二三科技

文章标题:RSA工具类:加解密和签名验签

文章地址:https://www.zhihuclub.com/153478.shtml

关于作者: 智云科技

热门文章

网站地图