一、简介:
RSA加密算法是最常用的非对称加密算法,CFCA在证书服务中离不了它。RSA是第一个比较完善的公开密钥算法,它既能用于加密,也能用于数字签名。这个算法经受住了多年深入的密码分析,虽然密码分析者既不能证明也不能否定RSA的安全性,但这恰恰说明该算法有一定的可信性,目前它已经成为最流行的公开密钥算法。
二、RSA的公钥、私钥的组成,以及加密、解密的公式可见于下表
三、使用方式:
① 假设A、B机器进行通信,已A机器为主;
② A首先需要用自己的私钥为发送请求数据签名,并将公钥一同发送给B;
③ B收到数据后,需要用A发送的公钥进行验证,已确保收到的数据是未经篡改的;
④ B验签通过后,处理逻辑,并把处理结果返回,返回数据需要用A发送的公钥进行加密(公钥加密后,只能用配对的私钥解密);
⑤ A收到B返回的数据,使用私钥解密,至此,一次数据交互完成。
四、代码示例:
- 第一步获取私钥,为签名做准备
/** * 读取私钥 返回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); }
- 签名示例 通过第一步得到的私钥,进行签名操作,具体请看以下代码:
/** * 私钥签名: 签名方法如下: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); }
- 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; } }
至此,签名验签已经完毕 - 提供一个从.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; }
- 附上所有代码: http://pan.baidu.com/share/link?shareid=23044&uk=298673178
- 转载自http://www.huosen.net/archives/124.html
相关推荐
工程根目录下mds5/src/com/目录下有两个例子: 其中DES.java是DES算法的对称加密解密 其中RSA.java是RSA算法的非对称加密解密 项目只给出了加密解密方法,并没有给出保存密钥的方法
可以直接运行成功的RSA加密解密示例 JAVA端采用公钥加密,服务端C#采用私钥解密。
1.用自己的私钥对加密密钥进行解密,得到对称密钥--也只有自己才能解密。 2.用对称密钥对密文进行解密,得到原文和签名。 3.计算原文的摘要 4.用对方的公钥对签名进行解密获取发送来的摘要--身份验证 5.将两个...
本程序实现了一个AES对称加密类和一个RSA非对称加密类,既可单独使用AES或RSA加密数据,也可结合使用,本程序给的示例是结合使用的,即用RSA加密AES的密钥,然后用AES的密钥进行数据加密,是一种更安全的技术.
使用 RSA 算法的图像...在这里,我们在 IMAGE 上实现 RSA(非对称密钥加密)算法,以使用两个密钥(私钥和公钥)进行加密和解密。要了解有关图像上的 RSA 加密的更多信息,请阅读我在存储库中上传的 pdf(RSA 图像)
主要介绍了ThinkPHP实现的rsa非对称加密类,结合实例形式分析了thinkPHP引入密钥文件实现rsa加密解密的相关操作技巧,需要的朋友可以参考下
基于openssl写的RSA的公钥加密,私钥解密,私钥加密,公钥解密的测试例子,密钥类型是rsa1024的PEM格式。
这篇文章主要介绍了Python如何基于rsa模块实现非对称加密与解密,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1、简单介绍: RSA加密算法是一种非对称加密...
RSA非对称加密算法,如果是公钥加密,就得用私钥解密,反过来也一样,私钥加密的就用公钥解密,以下是相关实现函数 /** * RSA私钥加密 * @param string $private_key 私钥 * @param string $data 要加密的字符串...
基于RSA非对称加密算法的一个例子,可提供各位学习和研究
PHP完整实现RSA加密类 1:签名 2:验签 3:数组自动生成sign键签名 4:数组直接验签方法 ...9:密钥使用 sha512,2048位RSA2标准,信息更安全 /*------ For Example ------ 代码里包函完整DEMO例子 ----*/
友情提醒:请按照user文档中的安装方法,如果你用的不是vc6就需要自己重新编译大数库(否则直接使用默认的ms32.lib),另外,可以参考所提供的cpp,里面有很多加密解密的例子,如AES,SHA等,轻松掌握~
RSA加密的内容长度有限,所以要么是只加密敏感内容,要么是结合其他对称加密例如AES使用(使用对称加密方式来加解密内容,用RSA来加解密对称加密的密钥)参考 这个已经说得挺详细了,也解决了其中遇到的一些问题,但...
非对称加密(又称公钥加密)指的是需要一个私有密钥一个公开密钥,两个不同的密钥的加解密体系。尽管不同,这个密钥对的这两个部分在算法上是有关联的。一个密钥将纯文本加密,另一个将密文解密。没有一个密钥能够...
php服务端与客户端交互、提供开放api时,通常需要对敏感的部分api数据传输进行数据加密,这时候rsa非对称加密就能派上用处了,下面通过一个例子来说明如何用php来实现数据的加密解密 1、加密解密的第一步是生成公钥...
这篇文章主要介绍了python RSA加密与解密实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 什么是RSA: RSA公开密钥密码体制。所谓的公开密钥密码体制...
Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。 设定字符串为“张三,你好,我是李四” 产生张三的密钥对(keyPairZhang) 张三生成公钥(publicKeyZhang...
对称加密网络应用2427.8 小结254第8章高等数据加密—非对称加密算法2568.1 非对称加密算法简述2568.2 密钥交换算法—DH 2588.3 典型非对称加密算法—RSA 2698.4 常用非对称加密算法—ElGamal2778.5 实例:非对称加密...
Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。 设定字符串为“张三,你好,我是李四” 产生张三的密钥对(keyPairZhang) 张三生成公钥(publicKeyZhang...