场景
Android+Java中使用RSA加密实现接口调用时的校验功能:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/111467394
在以上使用RSA非对称加密时所加密的key是固定的,如果限制只能在Android端和Java端能解密获取到key,在传输时使用密文,可以使用对称加密中的Aes加密。即使用同一个密钥进行加解密。
注:
博客主页:
https://blog.csdn.net/badao_liumang_qizhi
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。
实现
首先在SpringBoot项目中引入需要的依赖
<!-- Aes加密-->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>
然后新建一个工具类AesUtils
package com.ruoyi.web.controller.common; import org.apache.tomcat.util.codec.binary.Base64; import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.security.SecureRandom; import java.util.Random; /** * AES加、解密算法工具类 */ public class AesUtils { /** * 加密算法AES */ private static final String KEY_ALGORITHM = "AES"; /** * key的长度,Wrong key size: must be equal to 128, 192 or 256 * 传入时需要16、24、36 */ private static final Integer KEY_LENGTH = 16 * 8; /** * 算法名称/加密模式/数据填充方式 * 默认:AES/ECB/PKCS5Padding */ private static final String ALGORITHMS = "AES/ECB/PKCS5Padding"; /** * 后端AES的key,由静态代码块赋值 */ public static String key = "A3kppuf53Ch498Dj"; static { key = getKey(); } /** * 获取key */ public static String getKey() { StringBuilder uid = new StringBuilder(); //产生16位的强随机数 Random rd = new SecureRandom(); for (int i = 0; i < KEY_LENGTH / 8; i++) { //产生0-2的3位随机数 int type = rd.nextInt(3); switch (type) { case 0: //0-9的随机数 uid.append(rd.nextInt(10)); break; case 1: //ASCII在65-90之间为大写,获取大写随机 uid.append((char) (rd.nextInt(25) + 65)); break; case 2: //ASCII在97-122之间为小写,获取小写随机 uid.append((char) (rd.nextInt(25) + 97)); break; default: break; } } return uid.toString(); } /** * 加密 * * @param content 加密的字符串 * @param encryptKey key值 */ public static String encrypt(String content, String encryptKey) throws Exception { //设置Cipher对象 Cipher cipher = Cipher.getInstance(ALGORITHMS,new BouncyCastleProvider()); cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), KEY_ALGORITHM)); //调用doFinal byte[] b = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8)); // 转base64 return Base64.encodeBase64String(b); } /** * 解密 * * @param encryptStr 解密的字符串 * @param decryptKey 解密的key值 */ public static String decrypt(String encryptStr, String decryptKey) throws Exception { //base64格式的key字符串转byte byte[] decodeBase64 = Base64.decodeBase64(encryptStr); //设置Cipher对象 Cipher cipher = Cipher.getInstance(ALGORITHMS,new BouncyCastleProvider()); cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), KEY_ALGORITHM)); //调用doFinal解密 byte[] decryptBytes = cipher.doFinal(decodeBase64); return new String(decryptBytes); } public static void main(String[] args) { /* String sjkey = getKey(); System.out.println("获得随机key:" + sjkey);*/ //16位 String key = "A3kppuf53Ch498Dj"; //字符串 String str = "badaodechengxvyuan"; try { //加密 String encrypt = encrypt(str, key); //解密 String decrypt = decrypt(encrypt, key); System.out.println("加密前:" + str); System.out.println("加密后:" + encrypt); System.out.println("解密后:" + decrypt); } catch (Exception e) { e.printStackTrace(); } } }
首先需要调用main方法中获取获取key的代码
String sjkey = getKey(); System.out.println("获得随机key:" + sjkey);
注意这里的Base64的引入
import org.apache.tomcat.util.codec.binary.Base64;
然后将获取的Key手动复制给上面的
public static String key = "A3kppuf53Ch498Dj";
然后将此key交给Android
Android项目打开build.gradle引入相关依赖
//AES加密相关 // https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk16 implementation group: 'org.bouncycastle', name: 'bcprov-jdk16', version: '1.46'
在Android中新建工具类
package com.badao.badaoimclient.common; import android.util.Base64; import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; /** * AES加、解密算法工具类 */ public class AesUtils { /** * 加密算法AES */ private static final String KEY_ALGORITHM = "AES"; /** * key的长度,Wrong key size: must be equal to 128, 192 or 256 * 传入时需要16、24、36 */ private static final Integer KEY_LENGTH = 16 * 8; /** * 算法名称/加密模式/数据填充方式 * 默认:AES/ECB/PKCS5Padding */ private static final String ALGORITHMS = "AES/ECB/PKCS5Padding"; /** * 后端AES的key,由静态代码块赋值 */ public static String key; /** * 固定的Aes加密key */ public static String aesKey = "A3kppuf53Ch498Dj";//这里的Key要和进行加密时使用的key一致 /** * 解密 * * @param encryptStr 解密的字符串 * @param decryptKey 解密的key值 */ public static String decrypt(String encryptStr, String decryptKey) throws Exception { //base64格式的key字符串转byte byte[] decodeBase64 = Base64.decode(encryptStr,Base64.DEFAULT); //设置Cipher对象 Cipher cipher = Cipher.getInstance(ALGORITHMS,new BouncyCastleProvider()); cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), KEY_ALGORITHM)); //调用doFinal解密 byte[] decryptBytes = cipher.doFinal(decodeBase64); return new String(decryptBytes); } }
注意这里的Base64
import android.util.Base64;
将从Java中获取的key赋值到上面的变量。
然后就可以实现在Java端将某字符串进行加密,然后将密文传输到Android,在Android中使用相同的key将密文解密。
所以这里Android中只有解密的方法,如果想加密发送,则将Java的加密方法复制过来。
为了演示加解密,只在Java端进行调用演示