一、异常
1.java.security.NoSuchAlgorithmException: Cannot find any provider supporting AES/CBC/PKCS7Padding
解决办法:
1.引入相对应jdk版本的maven依赖 我这里使用的是jdk1.8
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15to18 -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15to18</artifactId>
<version>1.76</version>
</dependency>
2.在使用AES前,加入Security.addProvider(new BouncyCastleProvider());
见代码示例:
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.crush.weixin.entity.UserDO;
import com.crush.weixin.entity.WXAuth;
import com.crush.weixin.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.Random;
@Slf4j
@Component
public class WxService {
@Autowired
private StringRedisTemplate redisTemplate;
@Value("${weixin.session_key}")
private String sessionKey;
@Autowired
UserMapper userMapper;
static {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
}
//这是使用PKCS5Padding 的解密方式 测试下来与PKCS7Padding的结果毫无差别
// public String wxDecrypt(WXAuth wxAuth) throws Exception {
// String session_key = redisTemplate.opsForValue().get(sessionKey + wxAuth.getOpenid());
// log.info("session_Key-信息:" + session_key);
// byte[] encData = cn.hutool.core.codec.Base64.decode(wxAuth.getEncryptedData());
// byte[] iv = cn.hutool.core.codec.Base64.decode(wxAuth.getIv());
// byte[] key = cn.hutool.core.codec.Base64.decode(session_key);
// AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
// Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
// cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
// return new String(cipher.doFinal(encData), "UTF-8");
// }
//PKCS7Padding的解密方式
public String decrypt(WXAuth wxAuth) {
String session_key = redisTemplate.opsForValue().get(sessionKey + wxAuth.getOpenid());
//被加密的数据 import org.apache.tomcat.util.codec.binary.Base64;
byte[] dataByte = Base64.decodeBase64(wxAuth.getEncryptedData());
//加密秘钥
byte[] keyByte = Base64.decodeBase64(session_key);
//偏移量
byte[] ivByte = Base64.decodeBase64(wxAuth.getIv());
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC");
SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
parameters.init(new IvParameterSpec(ivByte));
cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
byte[] resultByte = cipher.doFinal(dataByte);
if (null != resultByte && resultByte.length > 0) {
String result = new String(resultByte, "UTF-8");
return result;
}
return null;
} catch (Exception e) {
log.error("解密失败",e);
throw new RuntimeException("解密失败");
}
}
}
我使用直接下载jar包,改变配置信息都无效,只有如上方法解决了问题
参考资料:
大家也可以试试下面的方法