通过JAVA代码实现数据加密,数据验签,对称加密,非对称加密;
一、Base64
Base64编码的作用:由于某些系统中只能使用ASCII字符。Base64就是用来将非ASCII字符的数据转换成ASCII字符的一种方法。它使用下面表中所使用的字符与编码。
而且base64特别适合在Http,mime协议下快速传输数据。
Base64原理,比如: a b
1、先转换为asill码:97 98
2、然后将asill码转换为8位数的二进制: 01100001 01100010
3、将8位数的二进制转换为6位数的一组的(不足6位后面补0);011000(Y) 010110(W) 001oo(I)(后两个00位为补的)
4、将转换为6位一组的二进制转换为64进制的(完) :YWI
1 public static void base64Test() throwsException {2 String src = "ab";3
4 //Base64加码
5 byte[] en = Base64.getEncoder().encode(src.getBytes("UTF-8"));6
7 //Base64解码
8 byte[] de =Base64.getDecoder().decode(en);9
10 System.out.println(new String(en, "UTF-8")); //YWI=
11 System.out.println(new String(de, "UTF-8")); //ab
12 }
二、消息摘要算法
1.MD5 ;2.SHA ;3.MAC
1 //MD5的实现代码
2 public static void md5Test() throwsException {3 String src = "abc";4
5 //用jdk实现:MD5
6 MessageDigest md = MessageDigest.getInstance("MD5");7 byte[] md5Bytes = md.digest(src.getBytes("UTF-8"));8
9 //(16进制字符串)和字节数组的互转[Hex类位于Apache的commons-codec包中]
10 System.out.println("JDK MD5:" +Hex.encodeHexString(md5Bytes));11
12 //用common-codes实现实现:MD5
13 System.out.println("common-codes MD5:" +DigestUtils.md5Hex(src.getBytes()));14 }15
16
17 //SHA1的实现代码
18 public static void sha1Test() throwsException {19 String src = "abc";20
21 //用jdk实现:SHA1
22 MessageDigest md = MessageDigest.getInstance("SHA");23 md.update(src.getBytes());24 System.out.println("jdk sha-1:" +Hex.encodeHexString(md.digest()));25
26 //用common codes实现实现:SHA1
27 System.out.println("common codes SHA1 - 1 :" +DigestUtils.sha1Hex(src.getBytes()));28 System.out.println("common codes SHA1 - 2 :" +DigestUtils.sha1Hex(src));29 }
三、数字签名
1.RSA ;2.DSA; 3.ECDSA
用于防止数据串改,但传输中过程是明文;
1 /**
2 * MD5withRSA数字签名3 *4 * 或简单的方式也可通过MD5或sha-1对传输数据进行签名;5 *6 */
7 public static void signTest() throwsException {8 String src = "abc";9
10 //1.初始化密钥
11 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");12 keyPairGenerator.initialize(512);13 KeyPair keyPair =keyPairGenerator.generateKeyPair();14 RSAPublicKey rsaPublicKey =(RSAPublicKey) keyPair.getPublic();15 RSAPrivateKey rsaPrivateKey =(RSAPrivateKey) keyPair.getPrivate();16
17 //将密钥字符串化
18 String privateKeyStr =encodeBase64Str(rsaPrivateKey.getEncoded());19 System.out.println("输出私钥-可自己保存用于加签:" +privateKeyStr);20 String publicKeyStr =encodeBase64Str(rsaPublicKey.getEncoded());21 System.out.println("输出公钥-可发送对方用于验签:" +publicKeyStr);22
23 //2.私钥进行签名(发送端)
24 byte[] dePrivateKey = decodeBase64(privateKeyStr); //对应 rsaPrivateKey.getEncoded()
25
26 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(dePrivateKey);
27 KeyFactory keyFactory = KeyFactory.getInstance("RSA");28 PrivateKey privateKey =keyFactory.generatePrivate(pkcs8EncodedKeySpec);29 Signature signature = Signature.getInstance("MD5withRSA");30 signature.initSign(privateKey);31 signature.update(src.getBytes());32 byte[] result =signature.sign();33 System.out.println("jdk rsa sign:" +Hex.encodeHexString(result));34
35 //3.公钥验证签名(接收端)
36 byte[] dePublicKey = decodeBase64(publicKeyStr);//对应 rsaPublicKey.getEncoded()
37
38 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(dePublicKey);
39 keyFactory = KeyFactory.getInstance("RSA");40 PublicKey publicKey =keyFactory.generatePublic(x509EncodedKeySpec);41 signature = Signature.getInstance("MD5withRSA");42 signature.initVerify(publicKey);43 signature.update(src.getBytes());44 boolean bool =signature.verify(result);45 System.out.println("jdk rsa verify:" +bool);46 }
四、对称加密算法
1.3DES; 2.AES; 3.PBE
对称加密特点:只有一个密钥
1 /**
2 * AES对称加密算法。 AES的ECB模式3 *4 *@throwsException5 */
6 public static void aesTest1() throwsException {7
8 String src = "abc";9
10 /**
11 * 生产密钥12 */
13 KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");14 keyGenerator.init(128);15 SecretKey secretKey =keyGenerator.generateKey();16 //获取密钥
17 byte[] keyBytes =secretKey.getEncoded();18 //将密钥字符串化
19 String secretKeyStr =encodeBase64Str(keyBytes);20 System.out.println("输出密钥-保存:" +secretKeyStr);21
22 /**
23 * 加密和解密可共用部分24 */
25 byte[] keyBytes_1 = decodeBase64(secretKeyStr); //keyBytes_1 等于 keyBytes26 //设置加密或解密模式为AES的ECB模式
27 Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");28 //KEY转换
29 Key key = new SecretKeySpec(keyBytes_1, "AES");30
31 //加密
32 cipher.init(Cipher.ENCRYPT_MODE, key);33 byte[] result =cipher.doFinal(src.getBytes());34 System.out.println("jdk aes encrypt:" +Hex.encodeHexString(result));35
36 //解密
37 cipher.init(Cipher.DECRYPT_MODE, key);38 result =cipher.doFinal(result);39 System.out.println("jdk aes decrypt:" + newString(result));40 }41
42 /**
43 * AES对称加密:AES的CBC模式44 *@throwsException45 */
46 public static void aesTest2() throwsException {47 Charset UTF8 =StandardCharsets.UTF_8;48 String src = "abc";49
50 /**
51 * 生产密钥52 */
53 KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");54 keyGenerator.init(128);55 SecretKey secretKey =keyGenerator.generateKey();56 //获取密钥
57 byte[] keyBytes =secretKey.getEncoded();58 //将密钥字符串化
59 String secretKeyStr =encodeBase64Str(keyBytes);60 System.out.println("输出密钥保存:" +secretKeyStr);61
62
63 /**
64 * 加密和解密可共用部分65 */
66 byte[] keyBytes_1 = decodeBase64(secretKeyStr); //keyBytes_1 等于 keyBytes67 //算法/模式/补码方式
68 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");69 //KEY转换
70 Key key = new SecretKeySpec(keyBytes_1, "AES");71 //使用CBC模式,需要一个向量iv,可增加加密算法的强度
72 IvParameterSpec iv = new IvParameterSpec(keyBytes_1, 0, 16);73
74
75 //加密
76 cipher.init(Cipher.ENCRYPT_MODE, key, iv);77 byte[] result =cipher.doFinal(src.getBytes(UTF8));78 String encryptStr =encodeBase64Str(result);79 System.out.println("jdk-aes-encrypt:" +encryptStr);80
81
82 //解密
83 cipher.init(Cipher.DECRYPT_MODE, key, iv);84 byte[] result_2 = cipher.doFinal(decodeBase64(encryptStr));
85 System.out.println("jdk-aes-decrypt:" + newString(result_2, UTF8));86
87
88 /**
89 * 提示:90 * AES 128/192/256 JDK默认使用的AES算法最高只能支持128位 如果使用192或256位的密钥,91 * 需要无政策限制文件(UnlimitedStrength Jurisdiction Policy Files)92 */
93 }
五、非对称加密算法
1.DH ;2.RSA; 3.ElGamal
特点:有两个密钥:公钥和私钥
1 /**
2 * RSA非对称加密(有2个密钥:公钥和私有)3 *@throwsException4 */
5 public static void rsaTest() throwsException {6 String src = "abc";7
8 //1.初始化发送方密钥
9 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");10 keyPairGenerator.initialize(512);11 KeyPair keyPair =keyPairGenerator.generateKeyPair();12 RSAPublicKey rsaPublicKey =(RSAPublicKey) keyPair.getPublic();13 RSAPrivateKey rsaPrivateKey =(RSAPrivateKey) keyPair.getPrivate();14
15 String privateKeyStr =encodeBase64Str(rsaPrivateKey.getEncoded());16 String publicKeyStr =encodeBase64Str(rsaPublicKey.getEncoded());17 System.out.println("Public Key:" +publicKeyStr);18 System.out.println("Private Key:" +privateKeyStr);19
20 //2.私钥加密、公钥解密 ---- 加密
21 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = newPKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());22 KeyFactory keyFactory = KeyFactory.getInstance("RSA");23 PrivateKey privateKey =keyFactory.generatePrivate(pkcs8EncodedKeySpec);24 Cipher cipher = Cipher.getInstance("RSA");25 cipher.init(Cipher.ENCRYPT_MODE, privateKey);26 byte[] result =cipher.doFinal(src.getBytes());27 System.out.println("私钥加密、公钥解密 ---- 加密:" +encodeBase64Str(result));28
29 //3.私钥加密、公钥解密 ---- 解密
30 X509EncodedKeySpec x509EncodedKeySpec = newX509EncodedKeySpec(rsaPublicKey.getEncoded());31 keyFactory = KeyFactory.getInstance("RSA");32 PublicKey publicKey =keyFactory.generatePublic(x509EncodedKeySpec);33 cipher = Cipher.getInstance("RSA");34 cipher.init(Cipher.DECRYPT_MODE, publicKey);35 result =cipher.doFinal(result);36 System.out.println("私钥加密、公钥解密 ---- 解密:" + newString(result));37
38
39 //4.公钥加密、私钥解密 ---- 加密
40 X509EncodedKeySpec x509EncodedKeySpec2 = newX509EncodedKeySpec(rsaPublicKey.getEncoded());41 KeyFactory keyFactory2 = KeyFactory.getInstance("RSA");42 PublicKey publicKey2 =keyFactory2.generatePublic(x509EncodedKeySpec2);43 Cipher cipher2 = Cipher.getInstance("RSA");44 cipher2.init(Cipher.ENCRYPT_MODE, publicKey2);45 byte[] result2 =cipher2.doFinal(src.getBytes());46 System.out.println("公钥加密、私钥解密 ---- 加密:" +encodeBase64Str(result2));47
48 //5.私钥解密、公钥加密 ---- 解密
49 PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = newPKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());50 KeyFactory keyFactory5 = KeyFactory.getInstance("RSA");51 PrivateKey privateKey5 =keyFactory5.generatePrivate(pkcs8EncodedKeySpec5);52 Cipher cipher5 = Cipher.getInstance("RSA");53 cipher5.init(Cipher.DECRYPT_MODE, privateKey5);54 byte[] result5 =cipher5.doFinal(result2);55 System.out.println("公钥加密、私钥解密 ---- 解密:" + newString(result5));56
57 /**
58 * 对于:“Illegal key size or default parameters”异常,是因为美国的出口限制,59 * Sun通过权限文件(local_policy.jar、US_export_policy.jar)做了相应限制。因此存在一些问题.60 * 需要下载Java6或Java7的无政策限制文件local_policy.jar和US_export_policy.jar两个文件,放在jre/lib/security 目录下。61 */
62 }
Base64的encode和decode的通用方法
1 public static String encodeBase64Str(byte[] str) {2 try{3 String result = new String(Base64.getEncoder().encode(str), "UTF-8");4 returnresult;5 } catch(UnsupportedEncodingException e) {6 e.printStackTrace();7 }8 return null;9 }10
11 public static byte[] decodeBase64(String str) {12 try{13 byte[] result = Base64.getDecoder().decode(str.getBytes("UTF-8"));14 returnresult;15 } catch(UnsupportedEncodingException e) {16 e.printStackTrace();17 }18 return null;19 }