`
zengshaotao
  • 浏览: 747072 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

RSA非对称加密java实现模拟

    博客分类:
  • java
 
阅读更多

Java中RSA非对称密钥加解密使用示例

 

一、简介:
RSA加密算法是最常用的非对称加密算法,CFCA在证书服务中离不了它。RSA是第一个比较完善的公开密钥算法,它既能用于加密,也能用于数字签名。这个算法经受住了多年深入的密码分析,虽然密码分析者既不能证明也不能否定RSA的安全性,但这恰恰说明该算法有一定的可信性,目前它已经成为最流行的公开密钥算法。

二、RSA的公钥、私钥的组成,以及加密、解密的公式可见于下表

三、使用方式:

①  假设A、B机器进行通信,已A机器为主;

②  A首先需要用自己的私钥为发送请求数据签名,并将公钥一同发送给B;

③  B收到数据后,需要用A发送的公钥进行验证,已确保收到的数据是未经篡改的;

④  B验签通过后,处理逻辑,并把处理结果返回,返回数据需要用A发送的公钥进行加密(公钥加密后,只能用配对的私钥解密);

⑤  A收到B返回的数据,使用私钥解密,至此,一次数据交互完成。

四、代码示例:

  1. 第一步获取私钥,为签名做准备。
    复制代码
    /** 
         * 读取私钥  返回PrivateKey 
         * @param path  包含私钥的证书路径 
         * @param password  私钥证书密码 
         * @return 返回私钥PrivateKey 
         * @throws KeyStoreException 
         * @throws NoSuchAlgorithmException 
         * @throws CertificateException 
         * @throws IOException 
         * @throws UnrecoverableKeyException 
         */  
        private static PrivateKey getPrivateKey(String path,String password)  
                throws KeyStoreException, NoSuchAlgorithmException, CertificateException,  
                IOException, UnrecoverableKeyException {  
            KeyStore ks = KeyStore.getInstance("PKCS12");  
            FileInputStream fis = new FileInputStream(path);  
            char[] nPassword = null;  
            if ((password == null) || password.trim().equals("")) {  
                nPassword = null;  
            } else {  
                nPassword = password.toCharArray();  
            }  
            ks.load(fis, nPassword);  
            fis.close();  
            Enumeration<String> en = ks.aliases();  
            String keyAlias = null;  
            if (en.hasMoreElements()) {  
                keyAlias = (String) en.nextElement();  
            }  
       
            return (PrivateKey) ks.getKey(keyAlias, nPassword);  
        }  
    复制代码

     

     
  2. 签名示例  通过第一步得到的私钥,进行签名操作,具体请看以下代码:
    复制代码
    /** 
         * 私钥签名: 签名方法如下:BASE64(RSA(MD5(src),privatekey)),其中src为需要签名的字符串, 
    privatekey是商户的CFCA证书私钥。 
         * @param plainText 待签名字符串 
         * @param path 签名私钥路径 
         * @param password  签名私钥密码 
         * @return 返回签名后的字符串 
         * @throws Exception 
         */  
        public static String sign(String plainText,String path,String password)  
                throws Exception  {  
            /* 
             * MD5加密 
             */  
            MessageDigest md5 = MessageDigest.getInstance("MD5");  
            md5.update(plainText.getBytes("utf-8"));  
            byte[] digestBytes = md5.digest();  
            /* 
             * 用私钥进行签名 RSA 
             * Cipher负责完成加密或解密工作,基于RSA 
             */  
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");  
            //ENCRYPT_MODE表示为加密模式  
            cipher.init(Cipher.ENCRYPT_MODE, getPrivateKey(path, password));  
            //加密  
            byte[] rsaBytes = cipher.doFinal(digestBytes);  
            //Base64编码  
            return Base64.byteArrayToBase64(rsaBytes); 
    复制代码

     

     
  3. B收到数据后,需要使用A提供的公钥信息进行验签,此处使用公钥的N、E进行验签
    首先通过公钥N、E得到公钥PublicKey,如下:

     

    复制代码
    /**  
         * 根据公钥n、e生成公钥 
         * @param modulus   公钥n串 
         * @param publicExponent  公钥e串 
         * @return 返回公钥PublicKey 
         * @throws Exception 
         */  
        public static PublicKey getPublickKey(String modulus, String publicExponent)  
                throws Exception {  
            KeySpec publicKeySpec = new RSAPublicKeySpec(  
                    new BigInteger(modulus, 16), new BigInteger(publicExponent, 16));  
            KeyFactory factory = KeyFactory.getInstance("RSA");  
            PublicKey publicKey = factory.generatePublic(publicKeySpec);  
            return publicKey;  
        }  
    复制代码

     

     

    得到公钥PublicKey后,再去验证签名,代码如下:

    复制代码
    /** 
         * 用公钥证书进行验签 
         * @param message  签名之前的原文 
         * @param cipherText  签名 
         * @param pubKeyn 公钥n串 
         * @param pubKeye 公钥e串 
         * @return boolean 验签成功为true,失败为false 
         * @throws Exception 
         */  
        public static boolean verify(String message, String cipherText,String pubKeyn,  
                String pubKeye) throws Exception {  
            Cipher c4 = Cipher.getInstance("RSA/ECB/PKCS1Padding");  
            // 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示解密模式  
            c4.init(Cipher.DECRYPT_MODE, getPublickKey(pubKeyn,pubKeye));  
            // 解密  
            byte[] desDecTextBytes = c4.doFinal(Base64.base64ToByteArray(cipherText));  
            // 得到前置对原文进行的MD5  
            String md5Digest1 = Base64.byteArrayToBase64(desDecTextBytes);  
            MessageDigest md5 = MessageDigest.getInstance("MD5");  
            md5.update(message.getBytes("utf-8"));  
            byte[] digestBytes = md5.digest();  
            // 得到商户对原文进行的MD5  
            String md5Digest2 = Base64.byteArrayToBase64(digestBytes);  
            // 验证签名  
            if (md5Digest1.equals(md5Digest2)) {  
                return true;  
            } else {  
                return false;  
            }  
        }  
    复制代码

    至此,签名验签已经完毕

  4. 提供一个从.cer文件读取公钥的方法:
    复制代码
    /** 
         * 读取公钥cer 
         * @param path .cer文件的路径  如:c:/abc.cer 
         * @return  base64后的公钥串 
         * @throws IOException 
         * @throws CertificateException 
         */  
        public static String getPublicKey(String path) throws IOException,  
        CertificateException{  
            InputStream inStream = new FileInputStream(path);  
            ByteArrayOutputStream out = new ByteArrayOutputStream();  
            int ch;  
            String res = "";  
            while ((ch = inStream.read()) != -1) {  
                out.write(ch);  
            }  
            byte[] result = out.toByteArray();  
            res = Base64.byteArrayToBase64(result);  
            return res;  
        }  
    复制代码

     

     
  5. 附上所有代码: http://pan.baidu.com/share/link?shareid=23044&uk=2986731784

    本文转自:http://www.huosen.net/archives/124.html
分享到:
评论

相关推荐

    java源码包---java 源码 大量 实例

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    java源码包4

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    java源码包3

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    JAVA上百实例源码以及开源项目源代码 java开源包2

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    java源码包2

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    JAVA上百实例源码以及开源项目

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    JAVA上百实例源码以及开源项目源代码

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密 Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。 设定字符串为“张三,你好,我是李四”...

    成百上千个Java 源码DEMO 3(1-4是独立压缩包)

    Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密 Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。 设定字符串为“张三,你好,我是李四”...

    JAVA 范例大全 光盘 资源

    实例162 RSA算法进行加密 464 实例163 RSA算法进行解密 466 实例164 创建DH共享密钥 468 实例165 用公钥计算消息摘要的验证码 472 实例166 利用DES加密/解密 474 第17章 Java多媒体 495 实例167 幸运52...

Global site tag (gtag.js) - Google Analytics