当前位置: 移动技术网 > IT编程>移动开发>Android > Android开发之常用的加密算法讲解

Android开发之常用的加密算法讲解

2019年01月08日  | 移动技术网IT编程  | 我要评论

荒芜心田,身度女主角王月,最新嗨曲

> 古典算法:凯撒加密

> ascii编码

> byte和bit:二进制字节和位关系

> base64编码和解密

> 对称加密算法:des、aes

> 非对称加密rsa

> 消息摘要:md5、sha1、sha256

> 数字签名:避免抓包篡改参数

> 只有是一家公司,有能力,必须使用加密算法

> 目标:独立封装对称加密算法、非对称加密算法、使用md5加密用户登录/注册信息

![](img/usage.png)

### 02.ascii编码

> ascii编码:美国信息标准交互码,就是用来显示西欧字符

![](img/ascii.png)

> 获取字符ascii编码

//获取单个字符ascii

char ch = 'a';

int ascii = ch;

//system.out.println(ascii);

//获取字符串ascii

string str = "hello";

char[] chararray = str.tochararray();

for (char c : chararray) {

int value = c;

system.out.println(value);

}

### 03.凯撒加密解密

> 古罗马大帝凯撒发明:对字符串偏移

![](img/kaiser.png)

public static string encrypt(string input, int key) {

stringbuilder stringbuilder = new stringbuilder();

//获取每一个字符ascii编码

char[] arr = input.tochararray();

for (char c : arr) {

int ascii = c;

//偏移一位

ascii = ascii + key;

//获取ascii对应的字符

char result = (char) ascii;

//system.out.print(result);

stringbuilder.append(result);

}

return stringbuilder.tostring();

}

public static string decrypt(string input, int key) {

stringbuilder stringbuilder = new stringbuilder();

//获取每一个字符ascii编码

char[] arr = input.tochararray();

for (char c : arr) {

int ascii = c;

//偏移一位

ascii = ascii - key;

//获取ascii对应的字符

char result = (char) ascii;

//system.out.print(result);

stringbuilder.append(result);

}

return stringbuilder.tostring();

}

### 04.频度分析法凯撒加密算法

> 根据统计学破解凯撒算法:一篇英文文章字母e出现的概率很高

### 05.byte和bit

> byte:字节,一个byte有8位,1byte=8bit

> bit:位

> 示例代码

string input = "a";//一个英文字母占1个字节(byte)

string input2 = "我爱你";//一个中文utf-8编码表中占3个字节,一个中文gbk编码表中占2个字节

byte[] bytes = input.getbytes();//获取字符对应的byte数组

system.out.println(bytes.length);

byte[] bytes2 = input2.getbytes();

byte[] bytes3 = input2.getbytes("gbk");

system.out.println(bytes2.length);

system.out.println("gbk编码:"+bytes3.length);

char[] chararray = input.tochararray();

for (char c : chararray) {

int ascii = c;

system.out.println(ascii);

//转成二进制

string binarystring = integer.tobinarystring(ascii);

system.out.println(binarystring);

}

### 06.常见对称加密算法介绍

> des:企业级开发使用频率很高,data encryption standard数据加密标准

> aes:advanced encryption standard,高级数据加密标准,比des破解难度大

> 底层机制:操作的不是字符,操作的是二进制(字符二进制显示成矩阵,矩阵变化)

### 07.des加密

> des:data encryption standard数据加密标准

> 掌握参考api文档实现加密算法

> 对称加密三部曲:

* 1.创建cipher对象,cipher加密算法核心类

* 2.初始化加密/解密模式

* 3.加密/解密

> 加密算法、安全领域大量使用getinstance(参数) 方法

public static void main(string[] args) {

string input = "我爱你";

string password = "12345678";//秘钥:des秘钥长度是64个bit(位)

try {

//  1.创建cipher对象,cipher加密算法核心类

cipher cipher = cipher.getinstance("des");

key key = new secretkeyspec(password.getbytes(), "des");

//  2.初始化加密/解密模式:以后只要是对象参数是int,说明有常量

cipher.init(cipher.encrypt_mode, key);//加密模式

//  3.加密

byte[] encrypt = cipher.dofinal(input.getbytes());

system.out.println("des加密="+new string(encrypt));

} catch (exception e) {

e.printstacktrace();

}

}

### 08.des解密

public static byte[] encrypt(string input, string password) {

try {

//  1.创建cipher对象,cipher加密算法核心类

cipher cipher = cipher.getinstance("des");

key key = new secretkeyspec(password.getbytes(), "des");

//  2.初始化加密/解密模式:以后只要是对象参数是int,说明有常量

cipher.init(cipher.encrypt_mode, key);//加密模式

//  3.加密

byte[] encrypt = cipher.dofinal(input.getbytes());

return encrypt;

} catch (exception e) {

e.printstacktrace();

}

return null;

}

/**

* des解密

*/

public static byte[] decrypt(byte[] input, string password) {

try {

//  1.创建cipher对象,cipher加密算法核心类

cipher cipher = cipher.getinstance("des");

key key = new secretkeyspec(password.getbytes(), "des");

//  2.初始化加密/解密模式:以后只要是对象参数是int,说明有常量

cipher.init(cipher.decrypt_mode, key);//解密模式

//  3.加密

byte[] decrypt = cipher.dofinal(input);

return decrypt;

} catch (exception e) {

e.printstacktrace();

}

return null;

}

### 09.base64编码和解码

> des加密后密文长度是8个整数倍

> 加密后比明文长度变长,所以编码表找不到对应字符,乱码

> 使用base64编码和解密:从apache现在

> 1.加密后密文使用base64编码

> 2.解密前对密文解码

public static string encrypt(string input, string password) {

try {

//  1.创建cipher对象,cipher加密算法核心类

cipher cipher = cipher.getinstance("des");

key key = new secretkeyspec(password.getbytes(), "des");

//  2.初始化加密/解密模式:以后只要是对象参数是int,说明有常量

cipher.init(cipher.encrypt_mode, key);//加密模式

//  3.加密

byte[] encrypt = cipher.dofinal(input.getbytes());

return base64.encode(encrypt);

} catch (exception e) {

e.printstacktrace();

}

return null;

}

/**

* des解密

*/

public static string decrypt(string input, string password) {

try {

//  1.创建cipher对象,cipher加密算法核心类

cipher cipher = cipher.getinstance("des");

key key = new secretkeyspec(password.getbytes(), "des");

//  2.初始化加密/解密模式:以后只要是对象参数是int,说明有常量

cipher.init(cipher.decrypt_mode, key);//解密模式

//  3.加密

byte[] decrypt = cipher.dofinal(base64.decode(input));

return new string(decrypt);

} catch (exception e) {

e.printstacktrace();

}

return null;

}

### 10.aes加密解密

public static string encrypt(string input, string password) {

try {

//对称加密三部曲

//1.创建cipher对象

cipher cipher = cipher.getinstance(transformation);

//secretkeyspec:秘钥规范 -> 将字符串秘钥转成对象

key key = new secretkeyspec(password.getbytes(), transformation);

//2.初始化加密/解密模式

cipher.init(cipher.encrypt_mode, key);

//3.加密

byte[] encrypt = cipher.dofinal(input.getbytes());

string encode = base64.encode(encrypt);

return encode;

} catch (exception e) {

e.printstacktrace();

}

return null;

}

/**

* aes解密

*/

public static string decrypt(string input, string password) {

try {

//对称加密三部曲

//1.创建cipher对象

cipher cipher = cipher.getinstance(transformation);

//secretkeyspec:秘钥规范 -> 将字符串秘钥转成对象

key key = new secretkeyspec(password.getbytes(), transformation);

//2.初始化加密/解密模式

cipher.init(cipher.decrypt_mode, key);

//3.加密

byte[] encrypt = cipher.dofinal(base64.decode(input));//解密前对密文解码

//string encode = base64.encode(encrypt);

return new string(encrypt);

} catch (exception e) {

e.printstacktrace();

}

return null;

}

### 11.对称加密密钥长度分析

> des秘钥长度:8个字符

> aes秘钥长度:16个字符

> des加密后密文长度是8的整数倍

> aes加密后密文长度是16的整数倍

### 12.工作模式和填充模式

> ios加密,android没有解密:工作模式和填充模式不一致

> 工作模式:如何加密(ecb:并行加密,分段加密,每一段不相互影响;cbc只能串行加密)

> 填充模式:加密后密文长度如果达不到指定整数倍(8个字节、16个字节),填充对应字符

### 13.工作模式填充模式的使用

> 默认工作模式/填充模式:ecb/pkcs5padding

> cbc工作模式:报错parameters missing,cbc模式需求额外参数

> nopadding不填充模式:des原文长度必须是8个字节整数倍,aes原文长度必须是16个字节整数倍

### 14.对称加密应用实战

> 算法:des、aes,企业级开发使用des足够安全,如果要求高使用aes

> 特点:可逆(加密后可以解密)

> 需求:从服务器获取数据,缓存到本地,加密

### 15.非对称加密算法rsa介绍

> rsa:到2008年为止,世界上还没有任何可靠的攻击rsa算法的方式

> 秘钥对:公钥和私钥,秘钥对不能手动指定,必须有生成

> 加密速度慢:必须分段加密,不能加密大文件

> 公钥加密私钥解密;私钥加密公钥解密

> 公钥互换:连个商家合作需要交互公钥,但是私钥不能别人

### 16.非对称加密rsa生成秘钥对

> 不能手动指定,必须由系统生成:公钥和私钥

//非对称加密三部曲

//1.创建cipher对象

cipher cipher = cipher.getinstance(transformation);

//秘钥对生成器

keypairgenerator generator = keypairgenerator.getinstance(algorithm);

//秘钥对

keypair keypair = generator.generatekeypair();

privatekey privatekey = keypair.getprivate();

publickey publickey = keypair.getpublic();

//获取公钥和私钥字符串

string priatekeystr = base64.encode(privatekey.getencoded());

string publickeystr = base64.encode(publickey.getencoded());

### 17.非对称加密rsa加密

> 公钥加密和私钥加密

public static string encryptbyprivatekey(string input, privatekey privatekey) {

string encode;

try {

//非对称加密三部曲

//1.创建cipher对象

cipher cipher = cipher.getinstance(transformation);

//2.初始化加密/解密模式

cipher.init(cipher.encrypt_mode, privatekey);//私钥加密

//3.加密/解密 

byte[] encryptbyprivatekey = cipher.dofinal(input.getbytes());

encode = base64.encode(encryptbyprivatekey);

return encode;

} catch (exception e) {

e.printstacktrace();

}

return null;

}

public static string encryptbypublickey(string input, publickey publickey) {

string encode;

try {

//非对称加密三部曲

//1.创建cipher对象

cipher cipher = cipher.getinstance(transformation);

//2.初始化加密/解密模式

cipher.init(cipher.encrypt_mode, publickey);//私钥加密

//3.加密/解密 

byte[] encryptbyprivatekey = cipher.dofinal(input.getbytes());

encode = base64.encode(encryptbyprivatekey);

return encode;

} catch (exception e) {

e.printstacktrace();

}

return null;

}

### 18.非对称加密rsa分段加密

> rsa每次最大只能加密117个字节

> 超过117字节,分段加密

public static string encryptbyprivatekey(string input, privatekey privatekey) {

string encode;

try {

byte[] bytes = input.getbytes();

//非对称加密三部曲

//1.创建cipher对象

cipher cipher = cipher.getinstance(transformation);

//2.初始化加密/解密模式

cipher.init(cipher.encrypt_mode, privatekey);//私钥加密

//3.分段加密

int offset = 0;//当前加密位置

//缓冲区

byte[] buffer = new byte[1024];

bytearrayoutputstream baos = new bytearrayoutputstream();

while(bytes.length - offset > 0){

if(bytes.length - offset >= max_encrypt_size){

//加密完整块

buffer = cipher.dofinal(bytes, offset, max_encrypt_size);//加密117字节

offset += max_encrypt_size;

}else{

//最后一块

buffer = cipher.dofinal(bytes, offset, bytes.length - offset);

offset = bytes.length;

}

baos.write(buffer);

}

encode = base64.encode(baos.tobytearray());

return encode;

} catch (exception e) {

e.printstacktrace();

}

return null;

}

### 19.非对称加密rsa分段解密

public static string decryptbyprivatekey(string input, privatekey privatekey) {

string encode;

try {

byte[] bytes = base64.decode(input);

//非对称加密三部曲

//1.创建cipher对象

cipher cipher = cipher.getinstance(transformation);

//2.初始化加密/解密模式

cipher.init(cipher.decrypt_mode, privatekey);//私钥解密

//3.分段加密

int offset = 0;//当前加密位置

//缓冲区

byte[] buffer = new byte[1024];

bytearrayoutputstream baos = new bytearrayoutputstream();

while(bytes.length - offset > 0){

if(bytes.length - offset >= max_decrypt_size){

//加密完整块

buffer = cipher.dofinal(bytes, offset, max_decrypt_size);//加密117字节

offset += max_decrypt_size;

}else{

//最后一块

buffer = cipher.dofinal(bytes, offset, bytes.length - offset);

offset = bytes.length;

}

baos.write(buffer);

}

encode = baos.tostring();

return encode;

} catch (exception e) {

e.printstacktrace();

}

return null;

}

### 20.非对称加密保存秘钥对

> 每次都生成秘钥对:安卓加密有肯能ios不能解密

> 第一次生成存储起来

keyfactory kf = keyfactory.getinstance(algorithm);

//字符串秘钥转成对象类型

privatekey privatekey = kf.generateprivate(new pkcs8encodedkeyspec(base64.decode(private_key)));

publickey publickey = kf.generatepublic(new x509encodedkeyspec(base64.decode(public_key)));

### 21.消息摘要介绍

> messagedigest:消息摘要,摘要信息(唯一的),软件用判断正版盗版软件

> 三个算法:md5、sha1、sha256

> 特点:

* 不可逆(通过密文不能推出明文,只能撞库)

* 加密后密文长度固定,1kb字符串和1g字符串加密结果长度一样

### 22.消息摘要md5的使用

public static string md5(string input) {

try {

stringbuilder stringbuilder = new stringbuilder();

//获取消息摘要对象

messagedigest md5 = messagedigest.getinstance(algorithm);

byte[] digest = md5.digest(input.getbytes());

string hex = hexutils.tohex(digest);

//system.out.println(hex);

return hex;

} catch (exception e) {

e.printstacktrace();

}

return null;

}

### 23.获取文件md5值

public static string md5file(string filepath){

fileinputstream fis = null;

try {

fis = new fileinputstream(filepath);

messagedigest md5 = messagedigest.getinstance(algorithm);

byte[] buffer = new byte[1024];

int len = 0;

while((len = fis.read(buffer)) != -1){

md5.update(buffer, 0, len);

}

byte[] digest = md5.digest();

//转成16进制

string hex = hexutils.tohex(digest);

return hex;

} catch (exception e) {

e.printstacktrace();

} finally{

ioutils.close(fis);

}

return null;

}

### 24.消息摘要sha1和sha256的使用

> md5:16(加密后密文长度16个字节),32(密文转成16进制32个字节)

> sha1:20(加密后密文长度20个字节),40(密文转成16进制40个字节)

> sha256:32(加密后密文长度32个字节),64(密文转成16进制64个字节)

### 25.消息摘要应用实战

> 开发中使用哪个算法:常用md5

> 应用场景:用户登录/注册,用户密码必须加密传输

> 只要是用户密码必须使用md5(不可逆的),服务器存储的是密文

inputstream ins = null;

string usrename = "heima104";

string password = "123456";

try {

string url = "https://120.77.241.119/encryptserver/login?username=" 

+ usrename + "&password=" + md5utils.md5(password);

url url2 = new url(url);

httpurlconnection conn = (httpurlconnection) url2.openconnection();

system.out.println(url2.touri().tostring());

ins = conn.getinputstream();

string result = ioutils.convertstreamtostring(ins);

system.out.println(result);

} catch (exception e) {

e.printstacktrace();

} finally {

ioutils.close(ins);

}

> 撞库破解md5:不可能穷尽所有密文,加密多次,加盐

### 26.数字签名

> rsa数字签名:消息摘要和非对称加密的组合(sha256withrsa)

> 作用:校验参数是否被篡改,保证数据传输安全

public static boolean verity(string input, publickey publickey, string sign) {

try {

//1.获取数字签名对象

signature signature = signature.getinstance(algorithm);

//2.初始化校验方法:必须使用公钥

signature.initverify(publickey);

signature.update(input.getbytes());

//3.开始校验

boolean verify = signature.verify(base64.decode(sign));

//system.out.println("校验结果:"+verify);

return verify;

} catch (exception e) {

e.printstacktrace();

}

return false;

}

public static string sign(string input, privatekey privatekey) {

try {

//1.获取数字签名对象

signature signature = signature.getinstance(algorithm);

//2.初始化签名:必须使用使用

signature.initsign(privatekey);

signature.update(input.getbytes());

//3.开始签名

byte[] sign = signature.sign();

string encode = base64.encode(sign);

//system.out.println("sign="+encode);

return encode;

} catch (exception e) {

e.printstacktrace();

}

return null;

}

### 27.数字签名流程图分析

> rsa数字签名流程图:借鉴设计公司加密系统

![](img/rsa-sign.png)

### 28.数字签名应用实战-时间戳

> 登录url,抓包可以重复登录

> 如何避免抓包重复登录:添加时间戳

> 设置登录超时时间:比如20秒钟

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网