转载请注明出处: http://blog.csdn.net/bbld_/article/details/38777491
概述
RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困 难,因此可以将乘积公开作为加密密钥,即公钥,而两个大素数组合成私钥。公钥是可发布的供任何人使用,私钥则为自己所有,供解密之用。关于RSA其它需要了解的知识,参考*:http://zh.wikipedia.org/zh-cn/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95
在项目开发中对于一些比较敏感的信息需要对其进行加密处理,我们就可以使用RSA这种非对称加密算法来对数据进行加密处理。
使用
秘钥对的生成
1、我们可以在代码里随机生成密钥对
- /**
- * 随机生成RSA密钥对
- *
- * @param keyLength
- * 密钥长度,范围:512~2048<br>
- * 一般1024
- * @return
- */
- public static KeyPair generateRSAKeyPair(int keyLength)
- {
- try
- {
- KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA);
- kpg.initialize(keyLength);
- return kpg.genKeyPair();
- } catch (NoSuchAlgorithmException e)
- {
- e.printStackTrace();
- return null;
- }
- }
通过这方法我们得到KeyPair后就可以调用 keyPair.getPrivate() 和 pair.getPublic()得到 私钥 和 公钥了。不过实际我们一般是使用2的方法把生成的密钥对保存起来,密钥自己保存,比如服务端,把公钥给客户端(Android)用于加密需要发送的数据,最后服务端根据私钥吧客户端加密的信息解密再处理。
2、通过OpenSSl工具生成密钥对
OpenSSl工具下载:OpenSSl工具 (64位的也可使用)使用OpenSSl工具生成密钥对的过程如下:
首先双击打开bin文件夹下的openssl.exe,打开之后是一个命令行窗口:
然后通过如下命令生成私钥:
- genrsa -out rsa_private_key.pem 1024
用文本类工具打开可看到里面的内容:
- -----BEGIN RSA PRIVATE KEY-----
- MIICXQIBAAKBgQCfRTdcPIH10gT9f31rQuIInLwe7fl2dtEJ93gTmjE9c2H+kLVE
- NWgECiJVQ5sonQNfwToMKdO0b3Olf4pgBKeLThraz/L3nYJYlbqjHC3jTjUnZc0l
- uumpXGsox62+PuSGBlfb8zJO6hix4GV/vhyQVCpG9aYqgE7zyTRZYX9byQIDAQAB
- AoGAO9+sYRtKC9xJDfcocfMxv+UT/1ic6EDgcqu6Uzwq+Jvwod9KlXqyQJqCr6T7
- pjfodc3RAZOTx4gCZJverBvz053RH5GawCdocEgaqbXAAWJOhA+9IEU0NUud7ckF
- yDko0QXLoGP9tanrMEt5zMqt8QxDyl6Xcij3mk8rivOgBJECQQDNTO6dZX8xCozc
- Ne0gzC53Gv/KQXANBBHMr7WkKUb2i5+tXkEJ5z3abx2ppEQXDr4AgJH8Gtbm6K7t
- EHV4ov4FAkEAxppD/iiT1/SVQq20be8CsiHpsjTPiestWQWdm1Qn/Y2nAkGkpCFp
- yEdUvVDPtQhRN9EqNggNAnwg5kMvsuwN9QJAfHBhQe4/hk5Kyz+0l+irUW6AFOxN
- KtaIo3TtuK98X/yJsOAstAACMeCgLi9vRjqdWFiWJCVwlU38mZ0cVx8UsQJBALzt
- M5Er+LiPKw5rQCD0JZRfPnkQU/3XgyQUe4Gv5PsHLcCvwXeBcafcc3hEz9JfPyPi
- Dk2oCvg6LPHfKBkFBaECQQCODcKX6DBWiyVxmPaJOOcF63KpCYDPkjeovIUHro1x
- ElR2GrQCC/9Q4C4vruOhBQ+vX8NMPnO6NBy5TLGDwMyc
- -----END RSA PRIVATE KEY-----
这里面的内容是标准的ASCII字符,中间的一大串字符就是私钥数据了。
然后通过如下命令生成公钥:
- rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout
打开文件看下里面的内容:
- -----BEGIN PUBLIC KEY-----
- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCfRTdcPIH10gT9f31rQuIInLwe
- 7fl2dtEJ93gTmjE9c2H+kLVENWgECiJVQ5sonQNfwToMKdO0b3Olf4pgBKeLThra
- z/L3nYJYlbqjHC3jTjUnZc0luumpXGsox62+PuSGBlfb8zJO6hix4GV/vhyQVCpG
- 9aYqgE7zyTRZYX9byQIDAQAB
- -----END PUBLIC KEY-----
可以看到是跟私钥的文件类似的。
这样密钥就基本生成了,不过这样密钥对的私钥是无法在代码中直接使用的,要想使用它需要借助RSAPrivateKeyStructure这个类,java是不自带的。所以为了方便使用,我们需要对私钥进行PKCS#8编码,命令如下:
- pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt
这条命令的结果依然是在bin文件夹生成了pkcs8_rsa_private_key.pem文件,打开内容如下:
- -----BEGIN PRIVATE KEY-----
- MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJ9FN1w8gfXSBP1/
- fWtC4gicvB7t+XZ20Qn3eBOaMT1zYf6QtUQ1aAQKIlVDmyidA1/BOgwp07Rvc6V/
- imAEp4tOGtrP8vedgliVuqMcLeNONSdlzSW66alcayjHrb4+5IYGV9vzMk7qGLHg
- ZX++HJBUKkb1piqATvPJNFlhf1vJAgMBAAECgYA736xhG0oL3EkN9yhx8zG/5RP/
- WJzoQOByq7pTPCr4m/Ch30qVerJAmoKvpPumN+h1zdEBk5PHiAJkm96sG/PTndEf
- kZrAJ2hwSBqptcABYk6ED70gRTQ1S53tyQXIOSjRBcugY/21qeswS3nMyq3xDEPK
- XpdyKPeaTyuK86AEkQJBAM1M7p1lfzEKjNw17SDMLnca/8pBcA0EEcyvtaQpRvaL
- n61eQQnnPdpvHamkRBcOvgCAkfwa1uboru0QdXii/gUCQQDGmkP+KJPX9JVCrbRt
- 7wKyIemyNM+J6y1ZBZ2bVCf9jacCQaSkIWnIR1S9UM+1CFE30So2CA0CfCDmQy+y
- 7A31AkB8cGFB7j+GTkrLP7SX6KtRboAU7E0q1oijdO24r3xf/Imw4Cy0AAIx4KAu
- L29GOp1YWJYkJXCVTfyZnRxXHxSxAkEAvO0zkSv4uI8rDmtAIPQllF8+eRBT/deD
- JBR7ga/k+wctwK/Bd4Fxp9xzeETP0l8/I+IOTagK+Dos8d8oGQUFoQJBAI4Nwpfo
- MFaLJXGY9ok45wXrcqkJgM+SN6i8hQeujXESVHYatAIL/1DgLi+u46EFD69fw0w+
- c7o0HLlMsYPAzJw=
- -----END PRIVATE KEY-----
可以看到中间的私钥内容有所变化了,这样的私钥我们在代码里就方便使用了。
以上的密钥文件使用时需要注意吧头和尾的字符串去掉,我们只取中间的内容。
代码中的使用
首先我们需要封装写个RSA的工具类,方便加密解密的操作。
- package com.example.rsa;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.math.BigInteger;
- import java.security.KeyFactory;
- import java.security.KeyPair;
- import java.security.KeyPairGenerator;
- import java.security.NoSuchAlgorithmException;
- import java.security.PrivateKey;
- import java.security.PublicKey;
- import java.security.interfaces.RSAPrivateKey;
- import java.security.interfaces.RSAPublicKey;
- import java.security.spec.InvalidKeySpecException;
- import java.security.spec.PKCS8EncodedKeySpec;
- import java.security.spec.RSAPublicKeySpec;
- import java.security.spec.X509EncodedKeySpec;
- import javax.crypto.Cipher;
- /**
- * @author Mr.Zheng
- * @date 2014年8月22日 下午1:44:23
- */
- public final class RSAUtils
- {
- private static String RSA = "RSA";
- /**
- * 随机生成RSA密钥对(默认密钥长度为1024)
- *
- * @return
- */
- public static KeyPair generateRSAKeyPair()
- {
- return generateRSAKeyPair(1024);
- }
- /**
- * 随机生成RSA密钥对
- *
- * @param keyLength
- * 密钥长度,范围:512~2048<br>
- * 一般1024
- * @return
- */
- public static KeyPair generateRSAKeyPair(int keyLength)
- {
- try
- {
- KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA);
- kpg.initialize(keyLength);
- return kpg.genKeyPair();
- } catch (NoSuchAlgorithmException e)
- {
- e.printStackTrace();
- return null;
- }
- }
- /**
- * 用公钥加密 <br>
- * 每次加密的字节数,不能超过密钥的长度值减去11
- 再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://www.cnblogs.com/captainbed