• 非对称加密算法RSA--转


    RSA 
        这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman。 
        这种加密算法的特点主要是密钥的变化,上文我们看到DES只有一个密钥。相当于只有一把钥匙,如果这把钥匙丢了,数据也就不安全了。RSA同时有两把钥匙,公钥与私钥。同时支持数字签名。数字签名的意义在于,对传输过来的数据进行校验。确保数据在传输工程中不被修改。 

    流程分析: 

    1. 甲方构建密钥对儿,将公钥公布给乙方,将私钥保留。
    2. 甲方使用私钥加密数据,然后用私钥对加密后的数据签名,发送给乙方签名以及加密后的数据;乙方使用公钥、签名来验证待解密数据是否有效,如果有效使用公钥对数据解密。
    3. 乙方使用公钥加密数据,向甲方发送经过加密后的数据;甲方获得加密数据,通过私钥解密。


    按如上步骤给出序列图,如下: 



    通过java代码实现如下:Coder类见 Java加密技术(一) 

    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.X509EncodedKeySpec;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.crypto.Cipher;
    
    /**
     * RSA安全编码组件
     * 
     * @author 梁栋
     * @version 1.0
     * @since 1.0
     */
    public abstract class RSACoder extends Coder {
        public static final String KEY_ALGORITHM = "RSA";
        public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
    
        private static final String PUBLIC_KEY = "RSAPublicKey";
        private static final String PRIVATE_KEY = "RSAPrivateKey";
    
        /**
         * 用私钥对信息生成数字签名
         * 
         * @param data
         *            加密数据
         * @param privateKey
         *            私钥
         * 
         * @return
         * @throws Exception
         */
        public static String sign(byte[] data, String privateKey) throws Exception {
            // 解密由base64编码的私钥
            byte[] keyBytes = 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 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 = 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(decryptBASE64(sign));
        }
    
        /**
         * 解密<br>
         * 用私钥解密
         * 
         * @param data
         * @param key
         * @return
         * @throws Exception
         */
        public static byte[] decryptByPrivateKey(byte[] data, String key)
                throws Exception {
            // 对密钥解密
            byte[] keyBytes = 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);
    
            return cipher.doFinal(data);
        }
    
        /**
         * 解密<br>
         * 用公钥解密
         * 
         * @param data
         * @param key
         * @return
         * @throws Exception
         */
        public static byte[] decryptByPublicKey(byte[] data, String key)
                throws Exception {
            // 对密钥解密
            byte[] keyBytes = 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);
    
            return cipher.doFinal(data);
        }
    
        /**
         * 加密<br>
         * 用公钥加密
         * 
         * @param data
         * @param key
         * @return
         * @throws Exception
         */
        public static byte[] encryptByPublicKey(byte[] data, String key)
                throws Exception {
            // 对公钥解密
            byte[] keyBytes = 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);
    
            return cipher.doFinal(data);
        }
    
        /**
         * 加密<br>
         * 用私钥加密
         * 
         * @param data
         * @param key
         * @return
         * @throws Exception
         */
        public static byte[] encryptByPrivateKey(byte[] data, String key)
                throws Exception {
            // 对密钥解密
            byte[] keyBytes = 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);
    
            return cipher.doFinal(data);
        }
    
        /**
         * 取得私钥
         * 
         * @param keyMap
         * @return
         * @throws Exception
         */
        public static String getPrivateKey(Map<String, Object> keyMap)
                throws Exception {
            Key key = (Key) keyMap.get(PRIVATE_KEY);
    
            return 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 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;
        }
    }

    再给出一个测试类: 

    import static org.junit.Assert.*;
    
    import org.junit.Before;
    import org.junit.Test;
    
    import java.util.Map;
    
    /**
     * 
     * @author 梁栋
     * @version 1.0
     * @since 1.0
     */
    public class RSACoderTest {
        private String publicKey;
        private String privateKey;
    
        @Before
        public void setUp() throws Exception {
            Map<String, Object> keyMap = RSACoder.initKey();
    
            publicKey = RSACoder.getPublicKey(keyMap);
            privateKey = RSACoder.getPrivateKey(keyMap);
            System.err.println("公钥: 
    
    " + publicKey);
            System.err.println("私钥: 
    
    " + privateKey);
        }
    
        @Test
        public void test() throws Exception {
            System.err.println("公钥加密——私钥解密");
            String inputStr = "abc";
            byte[] data = inputStr.getBytes();
    
            byte[] encodedData = RSACoder.encryptByPublicKey(data, publicKey);
    
            byte[] decodedData = RSACoder.decryptByPrivateKey(encodedData,
                    privateKey);
    
            String outputStr = new String(decodedData);
            System.err.println("加密前: " + inputStr + "
    
    " + "解密后: " + outputStr);
            assertEquals(inputStr, outputStr);
    
        }
    
        @Test
        public void testSign() throws Exception {
            System.err.println("私钥加密——公钥解密");
            String inputStr = "sign";
            byte[] data = inputStr.getBytes();
    
            byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey);
    
            byte[] decodedData = RSACoder
                    .decryptByPublicKey(encodedData, publicKey);
    
            String outputStr = new String(decodedData);
            System.err.println("加密前: " + inputStr + "
    
    " + "解密后: " + outputStr);
            assertEquals(inputStr, outputStr);
    
            System.err.println("私钥签名——公钥验证签名");
            // 产生签名
            String sign = RSACoder.sign(encodedData, privateKey);
            System.err.println("签名:
    " + sign);
    
            // 验证签名
            boolean status = RSACoder.verify(encodedData, publicKey, sign);
            System.err.println("状态:
    " + status);
            assertTrue(status);
    
        }
    
    }

    原文地址:http://snowolf.iteye.com/blog/381767

  • 相关阅读:
    Lua Websockts
    计算机软件保护条例软件著作权
    git protocol on port 9418 is no longer supported
    【自动化测试】pycharm中导入selenium
    Android Studio代码自动提示无效的解决办法
    【Java基础】Java分支结构程序设计例题
    EXCEL实现回归分析
    【性能测试】安装LoadRunner12.55版本时出现Critical error的解决方法
    Android Studio如何修改模拟器的路径
    MySQL让人又爱又恨的多表查询
  • 原文地址:https://www.cnblogs.com/davidwang456/p/3925444.html
Copyright © 2020-2023  润新知