云服务常见安全算法之RSA介绍
是唯一广泛接受并实现,第一个既能用于数据加密也能用于数字签名
对称加密:对信息的加解密都采用相同的密钥Key。
优点:简化加解密处理过程,只要在交换阶段,密钥没有泄露,那么加密数据的机密性跟报文完整性就 可以得到保证。
缺点:都要用到同一个key,更容易泄露。
非对称加密:密钥被分解为一对:公钥PK加密, 密钥SK解密(可互换)。公钥通过非保密方式公开,而私钥由解密方保存。
优点:安全性高。
缺点:加密和解密花费时间长、速度慢,只适合对少量数据进行加密。
2.RSA算法基础
互质关系:如果两个正整数,除了1以外,没有其他公因子,我们就称这两个数是互质关系。
任意两个质数构成互质关系
一个数是质数,另一个数只要不是前者的倍数,两者就构成互质关系。
如果两个数之中,较大的那个数是质数,则两者构成互质关系。
......
欧拉函数:求任意给定正整数n,在小于等于n的正整数之中,有多少个数与n构成互质关系?
n=1; T=ψ(n)=1;
n为质数;T=ψ(n)=n-1;
n为两个质数的乘积;n=PQ, T=ψ(n)=ψ(P)ψ(Q)=(P-1)(Q-1);
......
欧拉定理:如果两个正整数a和n互质,则n的欧拉函数 φ(n) 可以让下面的等式成立
T=ψ(n),a^T=1(mod(n))
模反元素:如果两个正整数a和n互质,那么一定可以找到整数b,使得 ab-1 被n整除。
ab=1(mod(n))
推出——————》RSA定理:
若P,Q是互异质数,n=PQ, T=ψ(n),另有正整数E与D,E与T互质,并使得(ED)mod(T)=1。
有正整数A,且A<PQ,设:
A^Emod(n)=C , C^Dmod(n)=B
则有A=B。
public static void simple() {
// 1.任选两个质数
Integer P = 11;
Integer Q = 13;
// 2.PQ相乘得到N
Integer N = P * Q;
// 3.N的欧拉函数
Integer T = (P - 1) * (Q - 1);// T = ψ(n)
// 4.任选一个与T互质的整数(小于T)作为密钥,
Integer E = 7; // 一般选择65537
// 5.计算另一个密钥
Integer D = null;
for (Integer i = 0; i < N; i++) {
if ((E * i) % T == 1) {
D = i;
}
}
// 明文为3 经过对公钥(N,E)的模指运算得到密文
System.out.println(new BigInteger("3").modPow(new BigInteger(E.toString()), new BigInteger(N.toString())));
// 密文为42 经过对密钥(N,D)的模指运算得到密文
System.out.println(new BigInteger("42").modPow(new BigInteger(D.toString()), new BigInteger(N.toString())));
}
被破解的可能性:
P、Q、N、T、E、D
传播中暴露的是:N、E、C
解密信息需要:N、D
数学难题:大数因式分解 N = P * Q
3.RSA加密 jdk类包实现
public static void cipher() {
try {
// 初始化密钥
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(3072);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
System.out.println("public key:" + Base64.encodeBase64String(rsaPublicKey.getEncoded()));
System.out.println("private key:" + Base64.encodeBase64String(rsaPrivateKey.getEncoded()));
// 私钥加密、公钥解密--加密
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] result = cipher.doFinal(str.getBytes());
System.out.println("私钥加密、公钥解密--加密:" + Base64.encodeBase64String(result));
// 私钥加密、公钥解密--解密
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));
// 公钥加密、私钥解密--加密
x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
keyFactory = KeyFactory.getInstance("RSA");
publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
result = cipher.doFinal(str.getBytes());
System.out.println("公钥加密、私钥解密--加密:" + Base64.encodeBase64String(result));
// 公钥加密、私钥解密--解密
pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
keyFactory = KeyFactory.getInstance("RSA");
privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
result = cipher.doFinal(result);
System.out.println("公钥加密、私钥解密--解密:" + new String(result));
} catch (Exception e) {
}
}
4.数字签名及实现
带有密钥(公钥、私钥)的消息摘要算法
用途:验证数据完整性,认证数据来源,抗否认
过程:1.对发送内容先生成有限长度的摘要(MD,SHA),再使用私钥进行加密,进而生成数字签名。
2.用公钥对数字签名进行解密获取加密内容(其实也就是摘要),再用与发送方相同的摘要算法对发送内空 生成摘要。
常见算法:RSA、DSA、ECDSA
public static void signature() {
try {
// 初始化密钥
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(3072);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
// 执行签名
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Signature signature = Signature.getInstance("MD5withRSA");
signature.initSign(privateKey);
signature.update(str.getBytes());
byte[] result = signature.sign();
System.out.println("rsa sign :" + Hex.encodeHexString(result));
// 验证签名
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
signature = Signature.getInstance("MD5withRSA");
signature.initVerify(publicKey);
signature.update(str.getBytes());
boolean bool = signature.verify(result);
System.out.println("rsa verify :" + bool);
} catch (Exception e) {
}
}
- 点赞
- 收藏
- 关注作者
评论(0)