非对称加密与解密:RSA
RSA由于公钥和私钥不同,所以非对称加密算法可以极大的提高文件的安全性,RSA是可逆的,一个字符串可以经过rsa加密后,经过解密后的字符串传到对端如服务器上,在进行解密即可(前提条件是服务器知道解密的私钥)。
实例:
public class RSAUtils {
public static byte[] encrypt(byte[] data, PrivateKey privateKey) {
byte[] ret = null;
if(data!=null&&data.length>0){
if(privateKey!=null&&privateKey.getEncoded().length>0){
Log.d("flag", "-----------Length: " + privateKey.getEncoded().length);
try {
//1、创造加密引擎cipher
Cipher cipher = Cipher.getInstance("RSA");
//2、初始化
cipher.init(Cipher.ENCRYPT_MODE,privateKey);
//3、对数据进行加密
ret = cipher.doFinal(data);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
}
}
return ret;
}
}
public class MainActivity extends AppCompatActivity {
private TextView show_key;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
show_key = ((TextView) findViewById(R.id.show_key));
}
public void btnGenerateKey(View view) {
//生成公钥私钥
try {
//1、得到创造者(keyPair)实例
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
//2、进行初始化
//参数代表key的长度
kpg.initialize(3096);
//3、生成keyPair,当中包含一对key就是公钥和私钥
KeyPair keyPair = kpg.generateKeyPair();
//3、1获取公钥
PublicKey aPublic = keyPair.getPublic();
byte[] aPublicEncoded = aPublic.getEncoded();
byte[] encode = Base64.encode(aPublicEncoded, Base64.DEFAULT);
//将公钥存到sp
SharedPreferences sp = getSharedPreferences("publicKey", MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
//向sp存入公钥
editor.putString("publicKey",new String(encode));
editor.commit();
//3.2获取私钥
PrivateKey aPrivate = keyPair.getPrivate();
byte[] encoded = aPrivate.getEncoded();
byte[] encode1 = Base64.encode(encoded, Base64.DEFAULT);
//将私钥存入文件
File file = new File(getCacheDir(),"aPrivate");
try {
FileOutputStream fos = new FileOutputStream(file);
//将私钥写入文件
fos.write(encode1);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
show_key.setText("公钥是: "+ new String(encode)+"\n"+
"私钥是: "+ new String(encode1)
);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
public void btnRSAEncrypt(View view) {
PrivateKey privateKey = null;
//私钥加密
File file = new File(getCacheDir(),"aPrivate");
try {
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//读取流
byte[] buf = new byte[1024];
while (true){
int len = fis.read(buf);
if(len==-1){
break;
}
baos.write(buf,0,len);
}
byte[] result = baos.toByteArray();
//转换成私钥
byte[] decode = Base64.decode(result, Base64.DEFAULT);
//私钥如何进行转化
KeyFactory factory = KeyFactory.getInstance("RSA");
//通过PKCS获取私钥
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decode);
privateKey = factory.generatePrivate(keySpec);
//获取公钥X509EncodedKeySpec
fis.close();
baos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
byte[] data = "一行白鹭上青天".getBytes();
byte[] result = RSAUtils.encrypt(data,privateKey);
//处理数据
if (result != null) {
byte[] encode = Base64.encode(result, Base64.DEFAULT);
show_key.setText(new String(encode));
}else {
show_key.setText("加密失败");
}
}
public void btnRSADecrypt(View view) {
}
}
MD5加密:
MD5英文全称“Message-Digest Algorithm 5”,翻译过来是“消息摘要算法5”,由MD2、MD3、MD4演变过来的,是一种单向加密算法,是不可逆的一种的加密方式。即只能加密不能解密。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
//工厂模式
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] hash = md5.digest("你们好啊,陌生人".getBytes());
Log.d("flag", "---------->hash.length :" + hash.length);
int length = hash.length;
for (int i = 0; i < length; i++) {
Log.d("flag", "------hashValue: " + hash[i]);
}
//将返回的hash值进行&运算:0xFF(255) 取低八位
//将0xFF转换成二进制:0000000000000000000…… 1111 1111
StringBuilder builder = new StringBuilder((hash.length) * 2);
//for循环进行&运算
for (int i = 0; i < length; i++) {
int result = hash[i] & 0xFF;
Log.d("flag", "------->result: " + result);
if (result <= 0x0f) {//判断进行运算后值小于等于16
builder.append(0);
}
//需要将十进制的result转换为16进制,显示结果就可以了
String hexString = Integer.toHexString(result);
builder.append(hexString);
}
Log.d("flag", "Md5Digest之后结果: " + builder.toString());
/**
* 没有判断是否小于等于16之前
* e3a796ad2d9f93d83e826f288dc254a
*
* 判断之后的数据
* e3a796ad2d9f93d83e0826f288dc254a
*
* 浏览器中数据
* e3a796ad2d9f93d83e0826f288dc254a
*/
Log.d("flag", "Md5Digest之后内容: " + builder.toString());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
}