公开密钥密码算法也叫双密钥密码算法或非对称密钥密码算法,它的加密密钥与解密密钥不同。这种算法需要形成一个在数学上是相关联的密钥对(一个公钥和一个私钥),使用其中一个密钥加密数据,用另一个密钥来解密。公钥可以公开传递,不需要安全信道,但与之对应的私钥必须保密。在图1中,发件人用收件人的公钥加密了一段数据,只有收件人用自己的私钥才能解密。
与对称密钥密码体制一样,非对称密钥密码体制也有很多种加密算法。常用的非对称加密算法包括RSA、Elgamal(离散对数)、ECC(椭圆曲线)等。它没有了对称加密算法密钥分配之类的问题,不必再保持密钥传递信道的保密性,但它的加密速度相对较低。实际上在通信时,通常使用对称加密算法来加密大量数据,仅在传递对称密钥的时刻才使用非对称加密算法。这样将非对称加密算法与对称加密算法结合使用,可以优势互补、优化性能。同时,非对称密钥算法还可以用来签名和防抵赖等。
RSA公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
RSA 加解密算法详解:
(1)选择一对不同的、足够大的素数p,q。 p=3 q=11
(2)计算n=pq。 n=33
(3)计算∮(n)=(p-1)(q-1),对p, q保密。 ∮(n)=20
(4)找一个与∮(n)互质的数e,且1<e< ∮(n)。 e=3
(5)计算d,使得de≡1 mod ∮(n)。 d=7
(6)公钥KU=(e,n),私钥KR=(d,n)。公钥{3,33} 私钥{7,33}
(7)加密时,先将明文变换成0至n-1的一个整数M。若明文较长,可先分割成适当的组,然后再进行交换。设密文为C,则加密过程为:C ≡ M ? (mod n)。
(8)解密过程为: M ≡ C ?(mod n)。
? 在理论上,rsa 的安全性取决于模n分解的困难性,但数学上至今还未证明分解模就是攻击rsa的最佳办法。
? 人们完全可以设想有另外的途径破译rsa,如求解密指数d或找到(p-1)(q-1)等。但这些途径都不比分解n来的容易。
/* * 用jdk实现RSA: * */public static void jdkRSA(String src){//1.初始化秘钥try {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(512);KeyPair keyPair = keyPairGenerator.generateKeyPair();RSAPublicKey rSAPublicKey = (RSAPublicKey)keyPair.getPublic();RSAPrivateKey private1 = (RSAPrivateKey)keyPair.getPrivate();System.out.println("puk :"+Base64.encodeBase64String(rSAPublicKey.getEncoded()));System.out.println("pvk :"+Base64.encodeBase64String(private1.getEncoded()));//2.私钥,公钥--加密PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(private1.getEncoded());KeyFactory instance = KeyFactory.getInstance("RSA");KeyFactory keyFactory = instance;PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, privateKey);byte[] result = cipher.doFinal(src.getBytes());System.out.println("私钥加密,公钥解密--加密:"+Base64.encodeBase64String(result));//3.私钥加密,公钥解密---解密X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rSAPublicKey.getEncoded());keyFactory=KeyFactory.getInstance("RSA");PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);cipher=Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, publicKey);result=cipher.doFinal(result);System.out.println("私钥加密,公钥解密---解密"+new String(result));//4.公钥加密,私密解密--加密x509EncodedKeySpec =new X509EncodedKeySpec(rSAPublicKey.getEncoded());keyFactory=KeyFactory.getInstance("RSA");publicKey = keyFactory.generatePublic(x509EncodedKeySpec);cipher=Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, publicKey);result=cipher.doFinal(src.getBytes());System.out.println("公钥加密,私密解密--加密"+Base64.encodeBase64String(result));//5公钥加密,私钥解密--解密pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(private1.getEncoded());keyFactory=KeyFactory.getInstance("RSA");privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);cipher=Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, privateKey);result=cipher.doFinal(result);System.out.println("公钥加密,私钥解密--解密"+ new String(result));} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}
ECC(Ellipse Curve Cryptography)椭圆曲线加密算法是1985年由基于椭圆曲线理论的公钥加密技术开发的。与传统的基于大质数因子分解困难性的加密方法不同,ECC通过椭圆曲线方程式的性质产生密钥。ECC 160bit算法等级,相当于RSA 1024bit密钥提供的保密强度,210bit与RSA2048算法强度相当,计算量则更小,处理速度更快,存储空间和传输带宽占用较少。
ECC 加解密算法详解:
1 ) ECDSA 签名
? 1、选择一条椭圆曲线Ep(a,b),和基点G;
? 2、选择私有密钥k(k<n,n为G的阶),利用基点G计算公开密钥K=kG;
? 3、产生一个随机整数r(r<n),计算点R=rG;
? 4、将原数据和点R的坐标值x,y作为参数,计算SHA1做为hash,即Hash=SHA1(原数据,x,y);
? 5、计算s≡r - Hash * k (mod n)
? 6、r和s做为签名值,如果r和s其中一个为0,重新从第3步开始执行
2) ECDSA 验证
? 1、接受方在收到消息(m)和签名值(r,s)后,进行以下运算
? 2、计算:sG+H(m)P=(x1,y1), r1≡ x1 mod p。
? 3、验证等式:r1 ≡ r mod p。
? 4、如果等式成立,接受签名,否则签名无效。