RSA加密解密及RSA加签验签

RSA安全性应用场景说明

  在刚接触RSA的时候,会混淆RSA加密解密和RSA加签验签的概念。简单来说加密解密是公钥加密私钥解密,持有公钥(多人持有)可以对数据加密,但是只有持有私钥(一人持有)才可以解密并查看数据;加签验签是私钥加签公钥验签,持有私钥(一人持有)可以加签,持有公钥(多人持有)可以验签。

  在金融行业在设计到数据交互传输的时候,需要考虑数据的安全性问题。下文通过介绍RSA的加密和加签两个特性,说明RSA加密技术在保障数据传输过程中的安全性以及实现数据的防篡改和防否机制的应用场景及代码实现。


RSA在数据安全上的应用

加密:数据传输的安全性

  RSA加密解密主要应用于数据传输的安全性上。通过公钥加密、私钥解密的方式,可以达到公钥持有者能够加密数据,但只有私钥持有者才能够解密数据。通过加密传输数据能够避免被第三方截取者轻易的拦截数据,而通过RSA非对称加密的特性也能够较好的保证第三方截取者在没有私钥的情况下读取数据内容。

加签:数据的防篡改、防否认机制

  数据的的防否认机制是指数据的接收者可以明确的知道数据的发送人。RSA的数字签名技术是将摘要信息用发送者的私钥(有且只有一人持有)加密,与原文一起传送给接收者。接收者只有用发送者的公钥才能解密被加密的摘要信息,然后用HASH函数对收到的原文产生一个摘要信息,与解密的摘要信息对比。如果相同,则说明数据是有持有私钥的发送者发出的(其他人没有私钥,无法生成一致的摘要信息)。因此在此基础上可以认为有且只有一个私钥的持有者才可以加签,达到数据的防止篡改防否认机制。


RSA数据安全传输的实现

  基于RSA的加密和验签功能,在对于数据传输安全性要求较高的交互应用中,可以对原始数据进行加密加签。具体流程如下图↓


示例工程

  GitHub项目地址:https://github.com/suyin58/rsa-demo


主要代码

package com.wjs.rsaDemo;

import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;

import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

/**
 * RSA安全编码组件
 */
public abstract class RSAUtil{
    public static final String KEY_ALGORITHM = "RSA";
    public static final String SIGNATURE_ALGORITHM = "SHA1WithRSA";

    private static final String PUBLIC_KEY = "RSAPublicKey";
    private static final String PRIVATE_KEY = "RSAPrivateKey";

    /**
     * 用私钥对信息生成数字签名
     *
     * @param data
     *            加密数据
     * @param privateKey
     *            Base64编码格式的私钥
     *
     * @return 经过Base64编码的字符串
     * @throws Exception
     */
    public static String sign(byte[] data, String privateKey) throws Exception {
        // 解密由base64编码的私钥
        byte[] keyBytes = HashUtil.decryptBASE64(privateKey);

        // 构造PKCS8EncodedKeySpec对象
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);

        // KEY_ALGORITHM 指定的加密算法
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

        // 取私钥匙对象
        PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);

        // 用私钥对信息生成数字签名
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initSign(priKey);
        signature.update(data);

        return HashUtil.encryptBASE64(signature.sign());
    }

    /**
     * 校验数字签名
     *
     * @param data
     *            加密数据
     * @param publicKey
     *            公钥
     * @param sign
     *            数字签名
     *
     * @return 校验成功返回true 失败返回false
     * @throws Exception
     *
     */
    public static boolean verify(byte[] data, String publicKey, String sign)
            throws Exception {

        // 解密由base64编码的公钥
        byte[] keyBytes = HashUtil.decryptBASE64(publicKey);

        // 构造X509EncodedKeySpec对象
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);

        // KEY_ALGORITHM 指定的加密算法
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

        // 取公钥匙对象
        PublicKey pubKey = keyFactory.generatePublic(keySpec);

        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initVerify(pubKey);
        signature.update(data);

        // 验证签名是否正常
        return signature.verify(HashUtil.decryptBASE64(sign));
    }

    /**
     * 解密<br>
     * 用私钥解密
     *
     * @param data
     * @param key Base64编码格式的私钥
     * @return
     * @throws Exception
     */
    public static byte[] decryptByPrivateKey(byte[] data, String key)
            throws Exception {
        byte[] decryptedData = null;

        // 对密钥解密
        byte[] keyBytes = HashUtil.decryptBASE64(key);

        // 取得私钥
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);

        // 对数据解密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        int maxDecryptBlockSize = getMaxDencryptBytesByPrivate(keyFactory, privateKey);
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        try {
            int dataLength = data.length;
            for (int i = 0; i < dataLength; i += maxDecryptBlockSize) {
                int decryptLength = dataLength - i < maxDecryptBlockSize ? dataLength - i : maxDecryptBlockSize;
                byte[] doFinal = cipher.doFinal(data, i, decryptLength);
                bout.write(doFinal);
            }
            decryptedData = bout.toByteArray();
        } finally {
            if (bout != null) {
                bout.close();
            }
        }

        return decryptedData;

    }

    /**
     * 将Base64编码的密文解密为字符串
     * @param base64Str
     * @param key
     * @return
     * @throws Exception
     * @author renteng
     * @date 2015年12月24日 下午12:35:34
     */
    public static String decryptByPrivateKeyToString(String base64Str, String key) throws Exception{
        byte[] data = HashUtil.decryptBASE64(base64Str);
        byte[] oriData = decryptByPrivateKey(data, key);

        return new String(oriData);
    }

    /**
     * 获取公钥加密可加密的最大数据字节长度
     * @param keyFactory
     * @param key
     * @return
     */
    private static int getMaxEncryptBytesByPublicKey(KeyFactory keyFactory, Key key){
        return getPublicKeyBitLength(keyFactory, key) / 8 - 11;
    }

       /**
     * 获取公钥解密每块的字节长度
     * @param keyFactory
     * @param key
     * @return
     */
    private static int getMaxDencryptBytesByPrivate(KeyFactory keyFactory, Key key){
        return getPrivateKeyBitLength(keyFactory, key) / 8;
    }

    /**
     * 获取公钥加密可加密的最大数据字节长度
     * @param keyFactory
     * @param key
     * @return
     */
    private static int getMaxEncryptBytesByPrivate(KeyFactory keyFactory, Key key){
        return getPrivateKeyBitLength(keyFactory, key) / 8 - 11;
    }

       /**
     * 获取公钥解密每块的字节长度
     * @param keyFactory
     * @param key
     * @return
     */
    private static int getMaxDencryptBytesByPublicKey(KeyFactory keyFactory, Key key){
        return getPublicKeyBitLength(keyFactory, key) / 8;
    }

    /**
     * 获取公钥的字节长度
     * @param keyFactory
     * @param key
     * @return
     */
    private static int getPublicKeyBitLength(KeyFactory keyFactory, Key key){
        try {
            RSAPublicKeySpec publicKeySpec = keyFactory.getKeySpec(key, RSAPublicKeySpec.class);
            return publicKeySpec.getModulus().bitLength();
        } catch (Exception e) {

        }
        return 2048;
    }

    /**
     * 获取私钥的字节长度
     * @param keyFactory
     * @param key
     * @return
     */
    private static int getPrivateKeyBitLength(KeyFactory keyFactory, Key key){
        try {
            RSAPrivateKeySpec publicKeySpec = keyFactory.getKeySpec(key, RSAPrivateKeySpec.class);
            return publicKeySpec.getModulus().bitLength();
        } catch (Exception e) {

        }

        return 2048;
    }

    /**
     * 解密<br>
     * 用公钥解密
     *
     * @param data
     * @param key Base64编码格式的公钥
     * @return
     * @throws Exception
     */
    public static byte[] decryptByPublicKey(byte[] data, String key)
            throws Exception {
        byte[] decryptedData = null;

        // 对密钥解密
        byte[] keyBytes = HashUtil.decryptBASE64(key);

        // 取得公钥
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key publicKey = keyFactory.generatePublic(x509KeySpec);

        // 对数据解密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, publicKey);

        int maxDecryptBlockSize = getMaxDencryptBytesByPublicKey(keyFactory, publicKey);
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        try {
            int dataLength = data.length;
            for (int i = 0; i < dataLength; i += maxDecryptBlockSize) {
                int decryptLength = dataLength - i < maxDecryptBlockSize ? dataLength - i
                    : maxDecryptBlockSize;
                byte[] doFinal = cipher.doFinal(data, i, decryptLength);
                bout.write(doFinal);
            }
            decryptedData = bout.toByteArray();
        } finally {
            if (bout != null) {
                bout.close();
            }
        }

        return decryptedData;
    }

    /**
     * 加密<br>
     * 用公钥加密
     *
     * @param data
     * @param key Base64编码格式的公钥
     * @return
     * @throws Exception
     */
    public static byte[] encryptByPublicKey(byte[] data, String key)
            throws Exception {
        byte[] encryptedData = null;
        // 对公钥解密
        byte[] keyBytes = HashUtil.decryptBASE64(key);

        // 取得公钥
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key publicKey = keyFactory.generatePublic(x509KeySpec);

        // 对数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);

        int maxEncryptBlockSize = getMaxEncryptBytesByPublicKey(keyFactory, publicKey);

        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        try {
            int dataLength = data.length;
            for (int i = 0; i < data.length; i += maxEncryptBlockSize) {
                int encryptLength = dataLength - i < maxEncryptBlockSize ? dataLength - i
                    : maxEncryptBlockSize;
                byte[] doFinal = cipher.doFinal(data, i, encryptLength);
                bout.write(doFinal);
            }
            encryptedData = bout.toByteArray();
        } finally {
            if (bout != null) {
                bout.close();
            }
        }

        return encryptedData;
    }

    /**
     * 加密<br>
     * 用私钥加密
     *
     * @param data 密文二进制数据
     * @param key BASE64编码的私钥字符串
     * @return
     * @throws Exception
     */
    public static byte[] encryptByPrivateKey(byte[] data, String key)
            throws Exception {
        byte[] encryptedData = null;

        // 对密钥解密
        byte[] keyBytes = HashUtil.decryptBASE64(key);

        // 取得私钥
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);

        // 对数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);

        int maxEncryptBlockSize = getMaxEncryptBytesByPrivate(keyFactory, privateKey);

        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        try {
            int dataLength = data.length;
            for (int i = 0; i < data.length; i += maxEncryptBlockSize) {
                int encryptLength = dataLength - i < maxEncryptBlockSize ? dataLength - i
                    : maxEncryptBlockSize;
                byte[] doFinal = cipher.doFinal(data, i, encryptLength);
                bout.write(doFinal);
            }
            encryptedData = bout.toByteArray();
        } finally {
            if (bout != null) {
                bout.close();
            }
        }

        return encryptedData;
    }

    /**
     * 取得私钥
     *
     * @param keyMap
     * @return
     * @throws Exception
     */
    public static String getPrivateKey(Map<String, Object> keyMap)
            throws Exception {
        Key key = (Key) keyMap.get(PRIVATE_KEY);

        return HashUtil.encryptBASE64(key.getEncoded());
    }

    /**
     * 取得公钥
     *
     * @param keyMap
     * @return
     * @throws Exception
     */
    public static String getPublicKey(Map<String, Object> keyMap)
            throws Exception {
        Key key = (Key) keyMap.get(PUBLIC_KEY);

        return HashUtil.encryptBASE64(key.getEncoded());
    }

    /**
     * 初始化密钥
     *
     * @return
     * @throws Exception
     */
    public static Map<String, Object> initKey() throws Exception {
        KeyPairGenerator keyPairGen = KeyPairGenerator
                .getInstance(KEY_ALGORITHM);
        keyPairGen.initialize(1024);

        KeyPair keyPair = keyPairGen.generateKeyPair();

        // 公钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();

        // 私钥
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

        Map<String, Object> keyMap = new HashMap<String, Object>(2);

        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
        return keyMap;
    }
}

RSAutil

package com.wjs.rsaDemo;

import java.security.MessageDigest;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

/**
 * 基础加密组件
 */
public abstract class HashUtil {
    public static final String KEY_SHA = "SHA";
    public static final String KEY_SHA_256 = "SHA-256";
    public static final String KEY_MD5 = "MD5";

    /**
     * MAC算法可选以下多种算法
     *
     * <pre>
     * HmacMD5
     * HmacSHA1
     * HmacSHA256
     * HmacSHA384
     * HmacSHA512
     * </pre>
     */
    public static final String KEY_MAC = "HmacMD5";

    /**
     * BASE64解密
     *
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] decryptBASE64(String key) throws Exception {
        return Base64.decodeBase64(key);
    }

    /**
     * BASE64加密
     *
     * @param key
     * @return
     * @throws Exception
     */
    public static String encryptBASE64(byte[] key) throws Exception {
        return Base64.encodeBase64String(key);
    }

    /**
     * MD5加密
     *
     * @param data
     * @return
     * @throws Exception
     */
    public static byte[] encryptMD5(byte[] data) throws Exception {

        MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
        md5.update(data);

        return md5.digest();

    }

    /**
     * SHA加密
     *
     * @param data
     * @return
     * @throws Exception
     */
    public static byte[] encryptSHA(byte[] data) throws Exception {

        MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
        sha.update(data);

        return sha.digest();
    }

    /**
     * SHA-256加密
     *
     * @param data 待hash的二进制数据
     * @return
     * @throws Exception
     */
    public static byte[] encryptSHA256(byte[] data) throws Exception {

        MessageDigest sha = MessageDigest.getInstance(KEY_SHA_256);
        sha.update(data);

        return sha.digest();
    }

    /**
     * 初始化HMAC密钥
     *
     * @return
     * @throws Exception
     */
    public static String initMacKey() throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);

        SecretKey secretKey = keyGenerator.generateKey();
        return encryptBASE64(secretKey.getEncoded());
    }

    /**
     * HMAC加密
     *
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] encryptHMAC(byte[] data, String key) throws Exception {

        SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);
        Mac mac = Mac.getInstance(secretKey.getAlgorithm());
        mac.init(secretKey);

        return mac.doFinal(data);

    }
}

HashUtil

package com.wjs.rsaDemo;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

public class RsaDemo {

    /**
     * 加签用公钥
     */
    public static String signPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3GFaW5S8GI7ejxhnVjhC6is3k5ZXY+eHK7hV42W7aSPuQ1dg72XZ2D/cLIdv4wNf8H3vf0e2O0YNwuwst6rD/BWey0yBUnToTm6xsJg5dCMYNQCocgtDrBTgHYSkZY/eno0MMn1KdRN0ILvAvz4BmENOkfuD3TEHgzXZS+prDZOKIHfW0HUYNEGk3LQC6VKQawKY+QO7k188wokV85FzmYFvjkkOE0UHuFL/p2zGnwVv+ZHq34TzZQaQNnO3/INQqxi+HiPfpD2oTJDY1+cAqukCD46hM+4qPx4t6A1fe+Tr8GE4DeGW3+MIqcuCs79cGj1Xtca8AoGCqK/Nx2Y0JwIDAQAB";

    /**
     * 加签用私钥
     */
    public static String signPrivateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDcYVpblLwYjt6PGGdWOELqKzeTlldj54cruFXjZbtpI+5DV2DvZdnYP9wsh2/jA1/wfe9/R7Y7Rg3C7Cy3qsP8FZ7LTIFSdOhObrGwmDl0Ixg1AKhyC0OsFOAdhKRlj96ejQwyfUp1E3Qgu8C/PgGYQ06R+4PdMQeDNdlL6msNk4ogd9bQdRg0QaTctALpUpBrApj5A7uTXzzCiRXzkXOZgW+OSQ4TRQe4Uv+nbMafBW/5kerfhPNlBpA2c7f8g1CrGL4eI9+kPahMkNjX5wCq6QIPjqEz7io/Hi3oDV975OvwYTgN4Zbf4wipy4Kzv1waPVe1xrwCgYKor83HZjQnAgMBAAECggEAJWZYIUaijUBhwMMRdm5h3L+s1N0kw42dQOwtl0PChFtWqhMAHmCYkbx0rxHlCQ+fjn6w0FbpNDH1T+koxZqzW+qHYlT/dXDlo7nhaejLh0wVZZlQ/NmwiFmalyfVhm7eBuZE9aSRqEC+6ncyhMIPHzn88YVPoZAaiEfxMpL7y/e3UAXfnzMFXqVi2ihMbtu6w1FUMgnWjy8WqqwgoTFVdR6GjWUROAtfTUwZe6Fw+KVm2+KKgMWPPE2SPxXp3q0T6AwI6Eg1RbIjUYUsl/9DkUdXJBt9G6eaNbY7WkeRrN8HKMCA1zOIv2sJWEnHkg2N6FgTHkSWIBXjiJ5vsphXUQKBgQDvcd0+J0PT1qAphgg3xTjQBim7MOsFG2VvQH0r72Fj4qy2BOsRyuotBJBQlgyq/csyduHew/068qWCCQb534dTvVtOXXQ1rSvyIM/UjFM0/5BExtKluz1zm2tQt0KDEOyZ1OnbGryuV8Ap8ftAfy1XkiVeqo1E9T6ej1kRzopABQKBgQDrngzRKsQPKDaCHb7Wn4QxYq5u8bYXn/EymynOjJcGxeJ/KotFCcemWFlWjIsi/k0sCJ3yWATARqCd7eSYcW/AmNpe2b/g4w699WvlSWq+E5hCA/GVwQpwRJSYN/PhDqdkBRngJ/AD8lf6CEGxG3SaMYCfXCkdFYwYYgdRGfUXOwKBgA3ERiwkpcmwNVUt15sdQ77yG8Qfc+O/R321/3xfLwJHLhbpAXrsZ7pe4M1BU0khfmVQYHwmWJDjEpD/Y99J8sXlxTIkPWI4qqYpLMnTp5UMfIb3x3Sv50CWVv01DCXs+y19CFUInICJmwrOVtvGdBzs0ik3NRgZ4ZfMNhrH/TrhAoGAB55BndW7Jx5OvOBHVlssBAjDyRSJpbPnMZKwxFvpWi+1xhTTEfVh/i/nG5RJv2Tni9/vc3GDHdBqyxBxDrjEOz71+JEj0hqlVGEGDxDTobeyeZf1DLmEI+MjxtQwT3uQz/wWPRgte4MvcwcnUJmpqH6nQP/S2Hzk3bj1sZqcQRcCgYBG4JCI7b1qJnvOPyP4Eqt6GcZ3OpbwkwKkiYQ2lwgn+wHT/7l3HfpTpBKZFMSknrbD11MzE2Q6niP6luG+HZPBsLyEQduipqaFe/GLmTGjljnj2wG3981sQluyrNlNPbDrTQKQERkcy6v8L6NHnIsYrUT/uHC6UJTqVYWjk1WVeQ==";

    /**
     * 加密用私钥
     */
    private static String encryptPrivateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCd4FMhHvZGRBAMuRqn0ZmvvNFBkYyGsf9NOaS+CMAgHB4ib+ciDE3lCfYZHhi0vV2iMMBIanwaNev4c0uu4WyeFLQkMAUbgW/iIo+pR8xocjo9RPsTxN0IOL4KpSeTLM2MQZKnyffBugoIt15mZzzij6lcXy2CI/2wcNKg4Nw6v1iZ8Et+wEgqlPVeASaTAFSjmJNQn4aIy8Fpzll8ADP9neUQCMOWG87lDbU9RCs0YqAFfo61MyYj+KbIvhWwyycZJIrKFwKsEn4tViB5UFegRP4DgSjEzq/glvnwgVNBDiYFOKZ8lqkS+bfhHBA+w+X+fJ2CTalKm3+NZTHYeX5DAgMBAAECggEAf9p1N/NtGkZwgP0+2v1havKMvH70wPhReubdxZAsl1RuCxF4qxgv1PaWOI0pEOXyeDDm5z5lNozIhrJIbl3cqsC1ikDhQf827nlywnKE1Wj8RTYh50acgdYCAXjybbvw0k8gR4XGgTr6eUiWyHN+2TPiwg3KOwSOpF8aFHNFpsSbwrOg7xlzNov6M28B/godUpGgPv0PuN7M6DMOi18QiwWSPa1ycnBt7tWZkyEl/vMdAV0be2RfY93Lvzgp8a/mI+A/c8hcBJj5vJDwJR3CnqKR5RceOPrA4eT2zXJOcR43DfWPo7Q+7Buii1ERoSF3Um4t5JpSr/2j2xHdJGmRMQKBgQDfODepUuiKMW5IPVdkdF62oDmF/CLkizbDsAPXeG6tWPZUYX7cHkoEuPY0LxACIcM3ZnZyCUBtIDMk7bLEIw3wuXqh+1hVQrS5VCosbVq6LxcT5MMQouMxRtHSScdIcsGUYZSIVjlXuQdDXzrKhg3LSTLdWdYAb4pIygHb0UbsxwKBgQC1D5Izs3UGFXpySMdeDo8eF4TkmQqGlYI1rEkZxHNcSH9BGTJH3EmuAb5/8UxSDWX7GPpLJeexSVHrfADYl4CmYpDITpihhaB+t68b9yHY7EwO/gF2QcTvvwIIfWJmjPyCJTwT6wRtmv5WQnt7tt0ObZq0tovJVdn8cbpyVLAOpQKBgQCaTWs0siorNSZN65FY0JSUW8fH1dZs88sElMzjCs4/KCsHg2nFUW7LOux+gDXps1sWFc803y5ZARQ5p9KWgMDnMeASzwNt1LHHFuYcVe+MmnayesVY37B7ZMAwRG3sp98m6hlZ8XisKixaJx8l1mr8pnnxx2MGZBRMYs/MGyuTCwKBgALxOtX+P5OWu8OprRu5Ltg1V6KDXilruo72usVhbOJ+BxtetnN2f/gE7TyVBkF7GEIpWL/p4Mb/wwYJoNXkOGH7zhCDPnW5fy8v+veAX5tv05iWxh1O2k1vFDBhIT07Y0sWIdDNC+hgEWwDbpBHG3aFj3MKWGEwNPemPXpoJ+hFAoGBAJioGALh7yp4bpHTdwrGtSWm8TdXBx8nC8rFNI9SUtSopafN2eHLwZ6PnVvN6kgCIlQ7HbxQruuGKiKd9UDTbEbFIaidUAoyzZm7/cYc0YJRVXnQNLiiz758VHtx1YEdscMXj10X4NSK8sRMjeWQhT1v5PaNafG65oSkuyFrIlPk";

    /**
     * 加密用公钥
     */
    public static String encryptPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAneBTIR72RkQQDLkap9GZr7zRQZGMhrH/TTmkvgjAIBweIm/nIgxN5Qn2GR4YtL1dojDASGp8GjXr+HNLruFsnhS0JDAFG4Fv4iKPqUfMaHI6PUT7E8TdCDi+CqUnkyzNjEGSp8n3wboKCLdeZmc84o+pXF8tgiP9sHDSoODcOr9YmfBLfsBIKpT1XgEmkwBUo5iTUJ+GiMvBac5ZfAAz/Z3lEAjDlhvO5Q21PUQrNGKgBX6OtTMmI/imyL4VsMsnGSSKyhcCrBJ+LVYgeVBXoET+A4EoxM6v4Jb58IFTQQ4mBTimfJapEvm34RwQPsPl/nydgk2pSpt/jWUx2Hl+QwIDAQAB";

    public static void main(String[] args) {

        // 组装数据
        encode("加签数据");

        // 解签
        System.out.println("解签后数据---->" + decode());

    }

    // 参数容器
    static Map<String, String> paramMap = new HashMap<String, String>();

    private static String charset = "utf-8";

    public static void encode(String bizParam) {
        try {

            // 使用网金社公钥对业务参数进行加密
            String bizParamEncrypt = HashUtil
                    .encryptBASE64(RSAUtil.encryptByPublicKey(bizParam.getBytes(charset), encryptPublicKey));
            paramMap.put("bizParams", URLEncoder.encode(bizParamEncrypt, charset));

            // 计算并组装签名
            String sign = RSAUtil.sign(bizParam.getBytes(charset), signPrivateKey);
            paramMap.put("sign", URLEncoder.encode(sign, charset));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String decode() {

        // 解密参数
        String bizParams = paramMap.get("bizParams");
        try {
            bizParams = URLDecoder.decode(bizParams, charset);
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }
        String bizParamsJson = null;
        try {
            bizParamsJson = new String(
                    RSAUtil.decryptByPrivateKey(HashUtil.decryptBASE64(bizParams), encryptPrivateKey));
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 验签
        checkSign(bizParamsJson, signPublicKey, paramMap.get("sign"));

        return bizParamsJson;
    }

    private static void checkSign(String data, String publicKey, String sign) {
        boolean verify = false;
        try {
            sign = URLDecoder.decode(sign, charset);
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }
        try {
            verify = RSAUtil.verify(data.getBytes(charset), publicKey, sign);
        } catch (Exception e) {
            e.getMessage();
        }
        if (!verify) {
            System.err.println("验签失败");
        } else {
            System.out.println("验签成功");
        }

    }

}
时间: 2024-10-26 05:48:06

RSA加密解密及RSA加签验签的相关文章

RSA加密解密及RSA签名和验证及证书

公钥是给别人的 发送密文使用公钥加密 验证签名使用公钥验证 私钥是自己保留的 接受密文使用私钥解密 发送签名使用私钥签名 上述过程逆转是不行的,比如使用私钥加密,使用公钥解密是不行的 证书的制作参考自使用X.509数字证书加密解密实务(一)-- 证书的获得和管理 打开VS开发命令,输入下面的命令: makecert -sr CurrentUser -ss My -n CN=MyTestCert -sky exchange -pe 从证书中读取私钥和公钥: /// <summary> /// 根

RSA加密解密及RSA签名和验证

原文:RSA加密解密及RSA签名和验证 1.RSA加密解密: (1)获取密钥,这里是产生密钥,实际应用中可以从各种存储介质上读取密钥 (2)加密 (3)解密2.RSA签名和验证 (1)获取密钥,这里是产生密钥,实际应用中可以从各种存储介质上读取密钥 (2)获取待签名的Hash码 (3)获取签名的字符串 (4)验证 3.公钥与私钥的理解: (1)私钥用来进行解密和签名,是给自己用的. (2)公钥由本人公开,用于加密和验证签名,是给别人用的.   (3)当该用户发送文件时,用私钥签名,别人用他给的公

C#自定义RSA加密解密及RSA签名和验证类实例

本文实例讲述了C#自定义RSA加密解密及RSA签名和验证类.分享给大家供大家参考.具体分析如下: 这个C#类自定义RSA加密解密及RSA签名和验证,包含了RSA加密.解密及签名所需的相关函数,带有详细的注释说明. using System; using System.Text; using System.Security.Cryptography; namespace DotNet.Utilities { /// <summary> /// RSA加密解密及RSA签名和验证 /// </

RSA加密解密(转)

RSA加密解密 对于RSA产生的公钥.私钥,我们可以有两种方式可以对信息进行加密解密.私钥加密-公钥解密 和 公钥加密-私钥解密RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.当时他们三人都在麻省理工学院工作.RSA就是他们三人姓氏开头字母拼在一起组成的. RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密算法.

C#-java RSA加密解密

using Org.BouncyCastle.Math;using Org.BouncyCastle.Crypto.Parameters;using Org.BouncyCastle.Security;using Org.BouncyCastle.Asn1.X509;using Org.BouncyCastle.X509;using Org.BouncyCastle.Asn1.Pkcs;using Org.BouncyCastle.Pkcs;using System;using System.S

RSA加密解密和读取公钥、私钥

/// <summary>     /// RSA加密解密及RSA签名和验证    /// </summary>     public class RSADE    {                 public RSADE()         {                     } #region RSA 加密解密 #region RSA 的密钥产生             /// <summary>        /// RSA 的密钥产生 产生私钥 和公

Java实现RSA密钥对并在加解密、加签验签中应用的实例

一.项目结构 二.代码具体实现 1.密钥对生成的两种方式:一种生成公钥私文件,一种生成公钥私串 KeyPairGenUtil.java package com.wangjinxiang.genkey.util; import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java.security.Key; import java.security.KeyPair; import java.security

Python中rsa模块【sign 加签验签】的使用

安装 pip install rsa 使用一 说明:简单入门使用  使用公钥加密  ----------->> 使用私钥进行解密 1 # -*- coding:utf-8 -*- 2 import rsa 3 4 5 def rsa_encrypt(d_str): 6 """ 7 生成私钥 和公钥 并接受字符串进行加密 8 :param d_str: 字符串 9 :return: 返回加密结果及私钥 10 """ 11 # 生成公钥和

RSA体系 c++/java相互进行加签验签--转

在web开发中,采用RSA公钥密钥体系自制ukey,文件证书登陆时,普遍的做法为:在浏览器端采用c++ activex控件,使用 c++的第三库openssl进行RAS加签操作,在服务器端采用java对客户端的签名进行验签操作.这就涉及到c++ openssl和java之间交互加签验签对客户端身份进行验证的过程. 如果你通过搜索查到我这边文章,相信你一定发现,采用openssl加签后的 数据,在java端却验签不成功,使用openssl验签可以通过.问题在于openssl的公钥发在服务端转换成j