Android常见的加密和算法

Stella981
• 阅读 637

1.不可逆的算法

主要为MD5和SHA-1算法。(二者都不属于加密只能算作一种算法)

相同点:都是使用目前比较广泛的散列(Hash)函数,就是把任意长度的输入,变换成固定长度的输出,该输出就是散列值。计算的时候所有的数据都参与了运算,其中任何一个数据变化了都会导致计算出来的Hash值完全不同。(理论上来讲产生的密文都有可能产生碰撞)

不同点:MD5输出是128位的,SHA-1输出是160位的,MD5比SHA1运行速度快,SHA1比MD5强度高。MD5一般用于文件的校验,SHA-1主要使用于数字签名标准。

MD5使用:

 1 public static String digest(String content){
 2     StringBuilder builder = new StringBuilder();
 3     try {
 4         MessageDigest msgDitest = MessageDigest.getInstance("MD5");
 5         msgDitest.update(content.getBytes());
 6         byte[] digests = msgDitest.digest();
 7         //将每个字节转为16进制
 8         for (int i=0;i<digests.length;i++){
 9             // TODO: 2019/11/10 需要再了解一下 
10             builder.append(Integer.toHexString(digests[i] & 0xff +8));//+8为加盐操作
11         }
12     } catch (NoSuchAlgorithmException e) {
13         e.printStackTrace();
14     }
15     return  builder.toString();
16 }

  SHA-1使用:

 1 public static String sha1Digest(String content){
 2    StringBuilder builder = new StringBuilder();
 3    try {
 4        MessageDigest msgDitest = MessageDigest.getInstance("SHA-1");
 5        msgDitest.update(content.getBytes());
 6        byte[] digests = msgDitest.digest();
 7        //将每个字节转为16进制
 8        for (int i=0;i<digests.length;i++){
 9            // TODO: 2019/11/10 再了解一下 
10            builder.append(Integer.toHexString(digests[i] & 0xff +8));//+8为加盐操作
11        }
12    } catch (NoSuchAlgorithmException e) {
13        e.printStackTrace();
14    }
15    return  builder.toString();
16 }

  2.可逆算法

其中可逆算法按照密钥的数量和加密规则又分为对称加密和非对称加密。

(1)对称加密

密钥可以自己指定,只有一把密钥。常用的对称加密算法有DES和AES两种。对称加密的速度快,但是缺点是安全性低,因为只要密钥暴漏,数据就可以被解密。

AES加密解密使用:

Android常见的加密和算法 Android常见的加密和算法

  1 package com.cn;
  2 
  3 import sun.misc.BASE64Decoder;
  4 import sun.misc.BASE64Encoder;
  5 
  6 import javax.crypto.*;
  7 import javax.crypto.spec.SecretKeySpec;
  8 import java.io.IOException;
  9 import java.io.UnsupportedEncodingException;
 10 import java.security.InvalidKeyException;
 11 import java.security.NoSuchAlgorithmException;
 12 import java.security.SecureRandom;
 13 import java.util.Scanner;
 14 
 15 public class SymmetricEncoder {
 16     /*
 17      * 加密
 18      * 1.构造密钥生成器
 19      * 2.根据ecnodeRules规则初始化密钥生成器
 20      * 3.产生密钥
 21      * 4.创建和初始化密码器
 22      * 5.内容加密
 23      * 6.返回字符串
 24      */
 25     public static String AESEncode(String encodeRules,String content){
 26         try {
 27             //1.构造密钥生成器,指定为AES算法,不区分大小写
 28             KeyGenerator keygen=KeyGenerator.getInstance("AES");
 29             //2.根据ecnodeRules规则初始化密钥生成器
 30             //生成一个128位的随机源,根据传入的字节数组
 31             keygen.init(128, new SecureRandom(encodeRules.getBytes()));
 32             //3.产生原始对称密钥
 33             SecretKey original_key=keygen.generateKey();
 34             //4.获得原始对称密钥的字节数组
 35             byte [] raw=original_key.getEncoded();
 36             //5.根据字节数组生成AES密钥
 37             SecretKey key=new SecretKeySpec(raw, "AES");
 38             //6.根据指定算法AES自成密码器
 39             Cipher cipher=Cipher.getInstance("AES");
 40             //7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEY
 41             cipher.init(Cipher.ENCRYPT_MODE, key);
 42             //8.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
 43             byte [] byte_encode=content.getBytes("utf-8");
 44             //9.根据密码器的初始化方式--加密:将数据加密
 45             byte [] byte_AES=cipher.doFinal(byte_encode);
 46             //10.将加密后的数据转换为字符串
 47             //这里用Base64Encoder中会找不到包
 48             //解决办法:
 49             //在项目的Build path中先移除JRE System Library,再添加库JRE System Library,重新编译后就一切正常了。
 50             String AES_encode=new String(new BASE64Encoder().encode(byte_AES));
 51             //11.将字符串返回
 52             return AES_encode;
 53         } catch (NoSuchAlgorithmException e) {
 54             e.printStackTrace();
 55         } catch (NoSuchPaddingException e) {
 56             e.printStackTrace();
 57         } catch (InvalidKeyException e) {
 58             e.printStackTrace();
 59         } catch (IllegalBlockSizeException e) {
 60             e.printStackTrace();
 61         } catch (BadPaddingException e) {
 62             e.printStackTrace();
 63         } catch (UnsupportedEncodingException e) {
 64             e.printStackTrace();
 65         }
 66 
 67         //如果有错就返加null
 68         return null;
 69     }
 70     /*
 71      * 解密
 72      * 解密过程:
 73      * 1.同加密1-4步
 74      * 2.将加密后的字符串反纺成byte[]数组
 75      * 3.将加密内容解密
 76      */
 77     public static String AESDncode(String encodeRules,String content){
 78         try {
 79             //1.构造密钥生成器,指定为AES算法,不区分大小写
 80             KeyGenerator keygen=KeyGenerator.getInstance("AES");
 81             //2.根据ecnodeRules规则初始化密钥生成器
 82             //生成一个128位的随机源,根据传入的字节数组
 83             keygen.init(128, new SecureRandom(encodeRules.getBytes()));
 84             //3.产生原始对称密钥
 85             SecretKey original_key=keygen.generateKey();
 86             //4.获得原始对称密钥的字节数组
 87             byte [] raw=original_key.getEncoded();
 88             //5.根据字节数组生成AES密钥
 89             SecretKey key=new SecretKeySpec(raw, "AES");
 90             //6.根据指定算法AES自成密码器
 91             Cipher cipher=Cipher.getInstance("AES");
 92             //7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY
 93             cipher.init(Cipher.DECRYPT_MODE, key);
 94             //8.将加密并编码后的内容解码成字节数组
 95             byte [] byte_content= new BASE64Decoder().decodeBuffer(content);
 96             /*
 97              * 解密
 98              */
 99             byte [] byte_decode=cipher.doFinal(byte_content);
100             String AES_decode=new String(byte_decode,"utf-8");
101             return AES_decode;
102         } catch (NoSuchAlgorithmException e) {
103             e.printStackTrace();
104         } catch (NoSuchPaddingException e) {
105             e.printStackTrace();
106         } catch (InvalidKeyException e) {
107             e.printStackTrace();
108         } catch (IOException e) {
109             e.printStackTrace();
110         } catch (IllegalBlockSizeException e) {
111             e.printStackTrace();
112         } catch (BadPaddingException e) {
113             e.printStackTrace();
114         }
115 
116         //如果有错就返加null
117         return null;
118     }
119 
120     public static void main(String[] args) {
121         SymmetricEncoder se=new SymmetricEncoder();
122         Scanner scanner=new Scanner(System.in);
123         /*
124          * 加密
125          */
126         System.out.println("使用AES对称加密,请输入加密的规则");
127         String encodeRules=scanner.next();
128         System.out.println("请输入要加密的内容:");
129         String content = scanner.next();
130         System.out.println("根据输入的规则"+encodeRules+"加密后的密文是:"+se.AESEncode(encodeRules, content));
131 
132         /*
133          * 解密
134          */
135         System.out.println("使用AES对称解密,请输入加密的规则:(须与加密相同)");
136         encodeRules=scanner.next();
137         System.out.println("请输入要解密的内容(密文):");
138         content = scanner.next();
139         System.out.println("根据输入的规则"+encodeRules+"解密后的明文是:"+se.AESDncode(encodeRules, content));
140     }
141 }

View Code

   DES加密解密使用:

Android常见的加密和算法 Android常见的加密和算法

 1 package com.cn;
 2 
 3 import javax.crypto.*;
 4 import javax.crypto.spec.DESKeySpec;
 5 import java.security.InvalidAlgorithmParameterException;
 6 import java.security.InvalidKeyException;
 7 import java.security.NoSuchAlgorithmException;
 8 import java.security.SecureRandom;
 9 import java.security.spec.InvalidKeySpecException;
10 
11 public class DESUtil {
12     public static byte[] encode(String mes) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidKeySpecException, InvalidAlgorithmParameterException {
13         SecureRandom random = new SecureRandom();
14         // TODO: 2019/11/10 密钥长度应该是要大于8
15         DESKeySpec desKey = new DESKeySpec("123abc123".getBytes());
16         //创建一个密匙工厂,然后用它把DESKeySpec转换成
17         SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
18         SecretKey securekey = keyFactory.generateSecret(desKey);
19         //Cipher对象实际完成加密操作
20         Cipher cipher = Cipher.getInstance("DES");
21         //用密匙初始化Cipher对象
22         cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
23         return cipher.doFinal(mes.getBytes());
24     }
25 
26     public static byte[] decode(byte[] encodeBytes) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {
27         // DES算法要求有一个可信任的随机数源
28         SecureRandom random = new SecureRandom();
29         // 创建一个DESKeySpec对象
30         DESKeySpec desKey = new DESKeySpec("123abc123".getBytes());
31         // 创建一个密匙工厂
32         SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
33         // 将DESKeySpec对象转换成SecretKey对象
34         SecretKey securekey = keyFactory.generateSecret(desKey);
35         // Cipher对象实际完成解密操作
36         Cipher cipher = Cipher.getInstance("DES");
37         // 用密匙初始化Cipher对象
38         cipher.init(Cipher.DECRYPT_MODE, securekey, random);
39         // 真正开始解密操作
40         return cipher.doFinal(encodeBytes);
41     }
42 }

View Code

  (2)非对称加密

常见的非对称加密算法是RSA;他有两把密钥,且是由程序生成的,不能自己指定;特点是加密速度比较慢,但是安全性比较高;加密和解密的规则是:公钥加密只能私钥解密,私钥加密只能公钥解密。

Android常见的加密和算法 Android常见的加密和算法

 1 package com.cn;
 2 
 3 import android.util.Base64;
 4 
 5 import javax.crypto.Cipher;
 6 import java.security.*;
 7 import java.security.interfaces.RSAPrivateKey;
 8 import java.security.interfaces.RSAPublicKey;
 9 import java.security.spec.PKCS8EncodedKeySpec;
10 import java.security.spec.X509EncodedKeySpec;
11 import java.util.HashMap;
12 import java.util.Map;
13 
14 public class RSAUtil {
15     private static Map<Integer, String> keyMap = new HashMap<Integer, String>();  //用于封装随机产生的公钥与私钥
16     public static void main(String[] args) throws Exception {
17         //生成公钥和私钥
18         genKeyPair();
19         //加密字符串
20         String message = "abc12301230";
21         System.out.println("随机生成的公钥为:" + keyMap.get(0));
22         System.out.println("随机生成的私钥为:" + keyMap.get(1));
23         String messageEn = encrypt(message,keyMap.get(0));
24         System.out.println(message + "\t加密后的字符串为:" + messageEn);
25         String messageDe = decrypt(messageEn,keyMap.get(1));
26         System.out.println("还原后的字符串为:" + messageDe);
27     }
28 
29     /**
30      * 随机生成密钥对
31      * @throws NoSuchAlgorithmException
32      */
33     public static void genKeyPair() throws NoSuchAlgorithmException {
34         // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
35         KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
36         // 初始化密钥对生成器,密钥大小为96-1024位
37         keyPairGen.initialize(1024,new SecureRandom());
38         // 生成一个密钥对,保存在keyPair中
39         KeyPair keyPair = keyPairGen.generateKeyPair();
40         RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();   // 得到私钥
41         RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  // 得到公钥
42         String publicKeyString = new String(Base64.encode(publicKey.getEncoded(), 0));
43         // 得到私钥字符串
44         String privateKeyString = new String(Base64.encode(privateKey.getEncoded(), 0));
45         // 将公钥和私钥保存到Map
46         keyMap.put(0,publicKeyString);  //0表示公钥
47         keyMap.put(1,privateKeyString);  //1表示私钥
48     }
49     /**
50      * RSA公钥加密
51      *
52      * @param str
53      *            加密字符串
54      * @param publicKey
55      *            公钥
56      * @return 密文
57      * @throws Exception
58      *             加密过程中的异常信息
59      */
60     public static String encrypt(String str, String publicKey) throws Exception{
61         //base64编码的公钥
62         byte[] decoded = Base64.decode(publicKey, 0);
63         RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
64         //RSA加密
65         Cipher cipher = Cipher.getInstance("RSA");
66         cipher.init(Cipher.ENCRYPT_MODE, pubKey);
67         String outStr = new String(Base64.encode(cipher.doFinal(str.getBytes("UTF-8")), 0));
68         return outStr;
69     }
70 
71     /**
72      * RSA私钥解密
73      *
74      * @param str
75      *            加密字符串
76      * @param privateKey
77      *            私钥
78      * @return 铭文
79      * @throws Exception
80      *             解密过程中的异常信息
81      */
82     public static String decrypt(String str, String privateKey) throws Exception{
83         //64位解码加密后的字符串
84         byte[] inputByte = Base64.decode(str.getBytes(), 0);
85         //base64编码的私钥
86         byte[] decoded = Base64.decode(privateKey, 0);
87         RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
88         //RSA解密
89         Cipher cipher = Cipher.getInstance("RSA");
90         cipher.init(Cipher.DECRYPT_MODE, priKey);
91         String outStr = new String(cipher.doFinal(inputByte));
92         return outStr;
93     }
94 }

View Code

  // TODO   AES加密模式, padding填充模式??

  参考资料:https://www.cnblogs.com/yegong0214/p/6498409.html

https://blog.csdn.net/u011897782/article/details/81163387

https://blog.csdn.net/joshho/article/details/88716314

        https://www.cnblogs.com/jying/p/9511247.html

          https://blog.csdn.net/qy20115549/article/details/83105736

       // TODO

https://www.cnblogs.com/think-in-java/p/5527389.html

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这