RSA加密算法
- 此Demo实现以下这几个功能
布局文件就不往出列了
1 . 生成公钥私钥
这是一个耗时操作,是通过随意选择两个大的质数经过一系列的复杂运算获得的,想了解算法自行百度,这里只说一下它如何使用!
case 的时候封装为一个方法
private void generateRsa() {
new Thread(new Runnable() {
@Override
public void run() {
//1.获取keyPareGenerator
try {
KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA");
//2.进行初始化,长度
keyPairGenerator.initialize(1024);
//3.获取密码
KeyPair keyPair = keyPairGenerator.generateKeyPair();
//4.获取私钥
privateKey = keyPair.getPrivate();
publicKey = keyPair.getPublic();
//展示数据:
final byte[] privateKeyEncoded = privateKey.getEncoded();
final byte[] publicKeyEncoded = publicKey.getEncoded();
//将密钥保存,如果不需要可以省略
SharedPreferences sp = MainActivity.this.getSharedPreferences("config", MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString("privateKey",Base64.encodeToString(privateKeyEncoded,Base64.DEFAULT));
editor.putString("publicKey",Base64.encodeToString(publicKeyEncoded,Base64.DEFAULT));
editor.commit();
//将获取到的内容显示到界面上
runOnUiThread(new Runnable() {
@Override
public void run() {
StringBuilder builder = new StringBuilder();
builder.append("私钥是:"+'\n');
builder.append(Base64.encodeToString(privateKeyEncoded,Base64.DEFAULT)+'\n');
builder.append("公钥是:"+'\n');
builder.append(Base64.encodeToString(publicKeyEncoded,Base64.DEFAULT)+'\n');
mResult.setText(builder.toString());
}
});
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
}).start();
}
2 . RSA加密(私钥加密)
直接从缓存中获取,SharedPreferences
//全局的常量声明
private String data = "Google Home 或 Amazon Echo 值得买吗?";
case R.id.encrypt:
//
String privateKey = sp.getString("privateKey", null);
byte[] decode = Base64.decode(privateKey, Base64.DEFAULT);
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
//私钥字节数组转换成私钥
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decode);
PrivateKey privateKey1 = keyFactory.generatePrivate(keySpec);
String encrypt = encrypt(data, privateKey1, 0);
mResult.setText(encrypt);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
break;
3 . RSA解密(公钥解密)
case R.id.decode:
String publicKey = sp.getString("publicKey", null);
byte[] decode1 = Base64.decode(publicKey, Base64.DEFAULT);
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decode1);
PublicKey publicKey1 = keyFactory.generatePublic(keySpec);
String data = mResult.getText().toString().trim();
String s = encrypt(data, publicKey1, 1);
mResult.setText(s);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
break;
- encrypt(data, publicKey1, 1);
该方法判断加密还是解密.
private String encrypt(String data, Key Key, int type) {
try {
Cipher cipher = Cipher.getInstance("RSA");
//设置密码
switch (type) {
case 0:
cipher.init(Cipher.ENCRYPT_MODE,Key);
break;
case 1:
cipher.init(Cipher.DECRYPT_MODE,Key);
break;
}
//区分加密解密:
switch (type) {
case 0:
byte[] bytes = cipher.doFinal(data.getBytes());
byte[] encode = Base64.encode(bytes, Base64.DEFAULT);
String result = new String(encode);
return result;
case 1:
byte[] decode = Base64.decode(data, Base64.DEFAULT);
byte[] doFinal = cipher.doFinal(decode);
String dResult = new String(doFinal);
return dResult;
}
}
//这里注意抛异常
return data;
4 . 数字签名
- 数字签名使用私钥进行加密 MD5withRSA
- 核心的方法:
1.Signature.getInstance(“MD5withRSA”);初始化操作
2.signature.initSign(privateKey); 使用私钥进行签名
3.signature.update(data.getBytes()); 签名的数据
4.byte[] sign = signature.sign();生成签名
5.使用Base64编码否则传输的为乱码
case R.id.md5Rsa://数字签名,使用私钥进行
try {
Signature signature = Signature.getInstance("MD5withRSA");
signature.initSign(privateKey);
signature.update(this.data.getBytes());
byte[] sign = signature.sign();//签名的数据
//将源文件和签名的数据一块发送给合作伙伴
mSignResult = Base64.encodeToString(sign, Base64.DEFAULT);
Log.d("flag", "----------------->rsa: 要传送给合作伙伴的数据: " +this.data+", 数字签名: "+mSignResult);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace();
}
break;
5 . 验证数字签名
- 核心方法
boolean verify = signature.verify();判断验证的结果
case R.id.md5vertify:
try {
Signature signature = Signature.getInstance("MD5withRSA");
//数字验证,使用公钥
signature.initVerify(mKeyPairPublic);
//update,传递过来的源文件
signature.update(this.data.getBytes());
//对签名进行验证 mSignResult
boolean verify = signature.verify(Base64.decode(mSignResult, Base64.DEFAULT));
Log.d("flag", "---------->rsa: 验证结果: " +verify);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace();
}
break;
- 最后结束程序将数据置空,减少内存的占用
@Override
protected void onDestroy() {
super.onDestroy();
result = null;
data = null;
}
判断公钥-私钥是否匹配
//取出私钥
//从sp中获取私钥
String privateKey = sp.getString("privateKey", null);
byte[] decode = Base64.decode(privateKey, Base64.DEFAULT);
//私钥字节数组转换成私钥
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
//PKCS8EncodedKeySpec ---->对应RSA 私钥
KeySpec keySpec = new PKCS8EncodedKeySpec(decode);
mKeyPairPrivate = keyFactory.generatePrivate(keySpec);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
String publicKey =this.publicKey;
byte[] decode1 = Base64.decode(publicKey, Base64.DEFAULT);
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
//X509EncodedKeySpec ----->RSA 公钥
KeySpec keySpec = new X509EncodedKeySpec(decode1);
mKeyPairPublic = keyFactory.generatePublic(keySpec);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}