JAVA RSA签名 验签 以及 加密解密

本文详细介绍了在JAVA中使用RSA进行签名、验签、加密和解密的步骤,包括商户与支付宝间的数据安全交互过程。通过示例代码展示了如何生成密钥对、加密、解密和验证签名,确保数据传输的安全性。

例如:商户和支付宝 验签 和 数据加密的逻辑:

①商户 生成自己的 RSA密钥对(包括公钥 和 私钥 ) 同样支付宝也会针对商户生成一个RSA 密钥对(包括公钥 和 私钥)

②商户和支付宝交换公钥。

③商户 用自己的 私钥和待签名的字符串 RSA 签名。 最终把自己的数据 加上 签名发给支付宝。

④支付宝使用商户提供的公钥对签名字符串 验签。 同理 支付宝发给我们的数据也是一样

⑤商户使用支付宝提供的公钥RSA加密数据。

⑥支付宝使用自己的私钥解密数据。 同理 支付宝发加密数据也是一样。


RSA 原理参照 http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html

下载openssl 地址 http://www.onlinedown.net/soft/85287.htm

使用OPENSSL 生成RSA公钥 私钥  参照 http://openhome.alipay.com/doc/viewKbDoc.htm?key=236698_236979_261975&type=info

命令如下:

直接在终端中运行openssl


生成原始密钥

genrsa -out rsa_private_key.pem 1024

生成java可用的密钥  cmd生成后复制出来

 pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM –nocrypt

生成公钥

rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

记住我们生成的密钥 和公钥 保存在代码中 不能有空格 和换行

本人测试代码如下


    public static final String  SIGN_ALGORITHMS = "SHA1WithRSA";
    private static final String ALGORITHM       = "RSA";
    private static final int MAX_ENCRYPT_BLOCK = 117; 
    private static final int MAX_DECRYPT_BLOCK = 128;  

   
    public static String encrypt(String content,String charset, String aliPubKey) {
        try {
            
            byte[] keyBytes = Base64.decode(aliPubKey);  
            X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);  
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);  
            Key pubKey = keyFactory.generatePublic(x509KeySpec);  
            
            // 对数据加密  
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);  
            
            byte[] data = content.getBytes(charset);
            byte[] splitData = splitData(data, cipher,MAX_ENCRYPT_BLOCK);  
            return Base64.encode(splitData);

        } catch (Exception e) {
            
            throw new RuntimeException(e);
        }
        
    }


    public static String decrypt(String content,String charset, String myPriKey){
        
        try {
            
            byte[] keyBytes = Base64.decode(myPriKey);  
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);  
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);  
            Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);  
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  
            cipher.init(Cipher.DECRYPT_MODE, privateK);  
            byte[] data = Base64.decode(content);
            byte[] splitData = splitData(data, cipher,MAX_DECRYPT_BLOCK);  
            return new String(splitData,charset);   

        } catch (Exception e) {
            
            throw new RuntimeException(e);
        }
    }
    

    private static byte[] splitData(byte[] data, Cipher cipher,int maxLen) throws IllegalBlockSizeException,
                                                                  BadPaddingException, IOException {
        int totalLen = data.length;  
        int offSet = 0 ;
        int index = 0;  
        byte[] cache;  
        
        ByteArrayOutputStream out = new ByteArrayOutputStream();  
        // 对数据分段解密  
        while (totalLen - offSet > 0) {  
            if (totalLen - offSet > maxLen) {  
                cache = cipher.doFinal(data, offSet, maxLen);  
            } else {  
                cache = cipher.doFinal(data, offSet, totalLen - offSet);  
            }  
            out.write(cache, 0, cache.length);  
            index++;  
            offSet = index * maxLen;  
        }  
        byte[] decryptedData = out.toByteArray();  
        out.close();
        return decryptedData;
        
    }
    

    public static String sign(String content, String charset, String myPriKey) {

        try {
            
            byte[] decodePubKey = Base64.decode(myPriKey);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodePubKey);
            KeyFactory factory = KeyFactory.getInstance(ALGORITHM);
            PrivateKey privateKey = factory.generatePrivate(keySpec);

            Signature signature = Signature.getInstance(SIGN_ALGORITHMS);

            signature.initSign(privateKey);
            signature.update(content.getBytes(charset));

            byte[] signed = signature.sign();

            return Base64.encode(signed);

        } catch (Exception e) {

            throw new RuntimeException(e);
        }

    }


    public static boolean verify(String content, String charset, String aliPubKey,String aliSign) {
        try {
            
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
            byte[] decodePubKey = Base64.decode(aliPubKey);
            
            PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(decodePubKey));

            Signature signature = Signature.getInstance(SIGN_ALGORITHMS);

            signature.initVerify(pubKey);
            signature.update(content.getBytes(charset));
            
            return signature.verify(Base64.decode(aliSign));

        } catch (Exception e) {
            
            throw new RuntimeException(e);
        }
    }
    
    
    public static void main(String[] args){
        
         String priKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAPKZrs4MTh0QjSWYQ8bkpIo8TsPLWtbA+PLdScMmz6GMMiWr4KYREAM6eTdzJG+NK/aK+ImihxOrJV/VJNvoSscdQxP7brvjbEQbFs+PKovMWEO7xJmBm3U27+9HOH9NFprSWCog9cfbtQXAXwTeGFyXybOgUtVsL17kcIJabYd3AgMBAAECgYA8kzsen9vxTeywcnCZ/QVIrv5LzT8FWHHQ0ohUfiBiCguLdHtHfAMviy4xNkLmx60uhkzAsSBhPN68KxBlCH+C88j3OiLtibCHTEiyTtjuT6C+hmh0UNY6HI5kcKbGqalGp1wvtf6FQ9GT6c5t8FdsT5vDua75VdSqkOg7ETu+gQJBAPxrjhQ6Lq5wb7aiCFnDkr6rD4quQRrYwEanjRv/p/3J8Udntmfq67Q2z1gWvHsj8tvdq9Ufn9FjPb8D7m1B58cCQQD2CnnHAd6r+L96q74EWrCUyzT0t4/i71cX0rlqT7Exo6N2frPkX3mPU0oQ45nxW3dUC0Q4SoDPFHYpsrnzMkLRAkAMpQqqArwh6un9uSI39O8d9A3EQbRrNt5y66PK+kSdFweqLwzZKdCC55f9bq4kcQmScAlSlNH5uEH4lqbT/FAzAkAwBTVlYPkLyX3dvF1Wzjh+ofaQ+K6tlRcDgE5N8IXd8Vk7DFmh7fx0u8XN7A4krDxq+9PxxKDFSfISC179l0axAkABIMCJqK+fE2MASJgliVkrwc/JvJM9BhL1RwcfIDvqvL00exyBlPMbwxEoJe//2F53/h1Kh/rN0bCGU21/njrv";
         String pubKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDyma7ODE4dEI0lmEPG5KSKPE7Dy1rWwPjy3UnDJs+hjDIlq+CmERADOnk3cyRvjSv2iviJoocTqyVf1STb6ErHHUMT+26742xEGxbPjyqLzFhDu8SZgZt1Nu/vRzh/TRaa0lgqIPXH27UFwF8E3hhcl8mzoFLVbC9e5HCCWm2HdwIDAQAB";
         
         String charset = "utf-8";
         String content = "RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard ";
        
        String sign = sign(content,charset,priKey);
        boolean result = verify(content,charset,pubKey,sign);
        
        String encrptyContent = encrypt(content,charset,pubKey);
        String realContent = decrypt(encrptyContent,charset,priKey);
        
        System.out.println(String.format("sign=%s result=%s realContent=%s",sign,result,realContent));
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值