高级
双保险
公钥,私钥
DH 密钥交换算法(是非对称加密的起源)
RSA 基于因子分解(应用范围最广,既能用于数据加密,也能用于数字签名)
ElGamal 基于离散对数
ECC 椭圆曲线加密
DH
对称加密算法提供了数据的安全性,同时也带来了密钥管理复杂性,如果想要发送加密的信息,必须事先约定好相同的算法,双方持有相同的密钥。密钥传递过程复杂,一旦密钥泄露,数据将很快的被破解掉。这就是对称加密带来的困扰。
密钥交换算法是通过构建本地密钥来解决这种对称加密带来的问题。
DH实现过程以及相关类:
1.初始化发送方密钥
KeyPairGenerator KeyPair常用的密钥的载体(密钥队)。包含两个信息,公钥publickey私钥privatekey。
KeyPair 能够得到公钥私钥
PublicKey公钥
2.初始化接收方密钥
KeyFactory密钥工厂,生成密钥
X509EncodedKeySpec类根据ASN.1标准进行密钥编码
DHPublicKey就是PublicKey具体的形式
DhParameterSpec随同DH使用的参数的集合(DH使用的参数都会放到这个集合中来使用)
KeyPairGenerator
PrivateKey私钥
3.密钥构建
KeyAgreement用来提供密钥一致性(或密钥交换)协议的功能。
SecretKey秘密密钥 对称密钥,生成一个分组的秘密密钥,提供了安全性的一些操作
KeyFactory
X509EncodedKeySpec
PublicKey
4.加密,解密
Cipher为加密解密提供密码功能的一个类
DH实现:
//1.初始化发送方密钥
KeyPairGenerator sendKeyPairGenerator = KeyPairGenerator.getInstance("DH");
//设置它的长度
sendKeyPairGenerator.initialize(512);
KeyPair sendKeyPair = sendKeyPairGenerator.generateKeyPair();
//发送方公钥的载体 需要发送给接收方(网络,文件。。)
byte[] sendPublicKeyEnc = sendKeyPair.getPublic().getEncoded();
//2.初始化接收方的密钥
KeyFactory receiverKeyFactory = KeyFactory.getInstance("DH");
X509EncodedKeySpec x509EncodedKeySpec =new X509EncodedKeySpec(sendPublicKeyEnc);
PublicKey receiverPublicKey = receiverKeyFactory.generatePublic(x509EncodedKeySpec);
//读取参数,再用这个参数去生成他自己的密钥
DHParameterSpec dhParameterSpec = ((DHPublicKey) receiverPublicKey).getParams();
KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance("DH");
receiverKeyPairGenerator.initialize(dhParameterSpec);
KeyPair receiverKeyPair = receiverKeyPairGenerator.generateKeyPair();
//3.密钥构建
KeyAgreement receiverKeyAgreement = KeyAgreement.getInstance("DH");
receiverKeyAgreement.init(receiverKeyPair.getPrivate());
receiverKeyAgreement.doPhase(receiverPublicKey,true);
SecretKey receiverDesKey = receiverKeyAgreement.generateSecret("DES");
byte[] receiverPublicKeyEnc = receiverKeyPair.getPublic().getEncoded();
KeyFactory sendKeyFactory = KeyFactory.getInstance("DH");
x509EncodedKeySpec =new X509EncodedKeySpec(receiverPublicKeyEnc);
PublicKey sendPublicKey = sendKeyFactory.generatePublic(x509EncodedKeySpec);
KeyAgreement sendKeyAgreement = KeyAgreement.getInstance("DH");
sendKeyAgreement.init(sendKeyPair.getPrivate());
sendKeyAgreement.doPhase(sendPublicKey,true);
//发送方的本地密钥
SecretKey sendDesKey = sendKeyAgreement.generateSecret("DES");
if(sendDesKey.equals(receiverDesKey)){
Log.d(TAG, "initDH: 双方密钥相同");
}
//4.加密
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE,sendDesKey);
byte[] result = cipher.doFinal(src.getBytes());
Log.d(TAG, "initDH: "+Base64.encodeToString(receiverPublicKeyEnc,0));
//5.解密
cipher.init(Cipher.DECRYPT_MODE,receiverDesKey);
result = cipher.doFinal(result);
Log.d(TAG, "initDH: "+new String(result));
RSA
唯一广泛接收并实现的一个非常通用并公开的算法。
数字加密,数字签名都会用到。
公钥加密,私钥解密
私钥加密,公钥解密
例:
//初始化密钥
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(512);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey)keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate();
Log.d(TAG, "initRSA: "+Base64.encodeToString(rsaPublicKey.getEncoded(),0));
Log.d(TAG, "initRSA: "+Base64.encodeToString(rsaPrivateKey.getEncoded(),0));
//加密
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(src.getBytes());
Log.d(TAG, "initRSA: +++"+Base64.encodeToString(result,0));
//解密 公钥解密 私钥加密
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);
Log.d(TAG, "initRSA: ---"+new String(result));
//加密 公钥加密 私钥解密
//解密 公钥加密 私钥解密
}catch (Exception e) {
e.printStackTrace();
}
RSA私钥加密,公钥解密:
1.发送者使用私钥加密数据
2.发送加密数据
3.接收者使用公钥解密数据
RSA公钥加密,私钥解密:
1.发送者使用公钥加密数据
2.发送加密数据
3.接收者使用私钥解密数据
ElGamal
和RSA不同的是只提供公钥加密算法。
jdk并没有提供给他的实现,他的实现是通过Bouncy Castle来提供的。
构建密钥和RSA基本上是一致的。算是RSA的一种补充。