经过一天的学习终于完成Android版基于公钥加密体制的Demo,如有雷同不甚荣幸。—–亚当爱自拍
- 加密技术的一些概念
- 运行环境及配置
- 代码实现
- 结束语(其实是建议啦)
概念
1. RSA算法:RSA算法基于一个十分简单的数论事实:将两个大质数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。
2. 公钥私钥:公钥通俗的讲是公开的大家可以知道的钥匙,私钥是指用户持自己持有的不可公开的钥匙,公钥与私钥是通过一套算法组成的秘钥对儿。
3. 数字签名:数字签名,顾名思义,就是使普通签章的数字化,他们的特性都是某人可以轻易制造签章,但他人却难以仿冒。数字签名可以永久地与被签署信息结合,无法自信息上移除。数字签名大致包含两个算法:一个是签署,使用私密钥匙处理信息或信息的哈希值而产生签章;另一个是验证,使用公开钥匙验证签章的真实性。RSA和DSA是两种最流行的数字签名机制。数字签名是公开钥匙基础建设(public key infranstructures, PKI)以及许多网络安全机制(SSL/TLS, VPNs等)的基础。
运行环境及配置
1. 运行环境:win10,AS,KeyStore Explorer 5.2.1,KeyTool.exe。
2. 配置:sdk,jdk
代码实现
1. EntryptUtils:
//加载密钥库keystore
public static KeyStore loadKeyStore(InputStream inputStream, String keystorePass) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
//提供密钥库类型
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
//读取keystore文件的输入流
InputStream in = inputStream;
keyStore.load(in, keystorePass.toCharArray());
return keyStore;
}
//从密钥库根据别名alias获得证书certificate
public static Certificate getCertFromKStore(String alias, KeyStore keyStore) throws KeyStoreException{
return keyStore.getCertificate(alias);
}
//非对称加密
public static byte[] asymmetricEncrypt(String transformation, byte[] plainText, PublicKey key) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException{
Cipher cipher = Cipher.getInstance(transformation);
cipher.init(Cipher.ENCRYPT_MODE, key);
cipher.update(plainText);
return cipher.doFinal();
}
//非对称解密
public static byte[] asymmetricDecrypt(String transformation, byte[] cipherText, PrivateKey key) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException{
Cipher cipher = Cipher.getInstance(transformation);
cipher.init(Cipher.DECRYPT_MODE, key);
cipher.update(cipherText);
return cipher.doFinal();
}
2. EncryptActivity
*初始化*
String keystorePass ;
String certPass ;
String alias ;
String source = "www.baidu.com";
*秘钥库的获取*
try {
keyStore = EncrytUtils.loadKeyStore(getResources().getAssets().open("rio"), keystorePass);
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
*私钥的获取*
try {
privateKey = EncrytUtils.getPrivateKey(keyStore, alias, certPass);
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
*公钥的获取*
PublicKey publicKey = null;
try {
publicKey = EncrytUtils.getPublicKey(keyStore.getCertificate(alias));
} catch (KeyStoreException e) {
e.printStackTrace();
}
*使用公钥加密*
byte[] enctypted_pub = new byte[0];
try {
enctypted_pub = EncrytUtils.asymmetricEncrypt("RSA/ECB/PKCS1Padding",source.getBytes("UTF-8"),publicKey);
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
*加密后的数据*
System.out.println("加密算法(公钥):" + publicKey.getAlgorithm());
System.out.println("公钥:" + publicKey.getEncoded());
System.out.println("公钥加密后的数据(十六进制):" + StringUtils.byte2Hex(encrypted));
*私钥解密*
byte[] decrypted_priv = new byte[0];
try {
decrypted_priv = EncrytUtils.asymmetricDecrypt("RSA/ECB/PKCS1Padding", enctypted_pub, privateKey);
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
*解密后的数据*
System.out.println("解密算法(私钥):" + privateKey.getAlgorithm());
System.out.println("私钥:" + privateKey.getEncoded());
System.out.println("私钥解密后数据(字节):" + StringUtils.byte2Hex(decrypted_priv));
*解密后的明文*
System.out.println("私钥解密后的数据(明文):" + new String(decrypted_priv, "UTF-8"));
下篇再讲证书下的签名与验证吧(该去写接口了文档了…)