javax.crypto.spec.SecretKeySpec

今天做接口遇到一个棘手的问题,就是接口传 数据需要AES加密,我在本地(windows)调试已经已经成功了,可是发布到服务器(Linux)上面老是出现java.security.InvalidKeyException: No installed provider supports this key: javax.crypto.spec.SecretKeySpec 本以为是jdk 的问题(本地用jdk1.6 服务器用jdk1.5 ),可以经过排除不是。以下是解决此问题的方法(此方法不能保证一定处理类似的问题):

到Linux上面修改jdk1.5的安全文件,使其支持AES/CTR/PKCS5Padding的填充方式。
1) 将bcprov-jdk15-141.Jar分别复制到下列路径
/usr/java/jdk1.5.0_06/jre/lib
/usr/java/jdk1.5.0_06/jre/lib/ext/
2) 修改/usr/java/jdk1.5.0_06/jre/lib/security/java.Security文件
   在文件最后添加以下内容
security.provider.1=sun.security.provider.Sun
security.provider.2=com.sun.net.ssl.internal.ssl.Provider
security.provider.3=org.bouncycastle.jce.provider.BouncyCastleProvider

转载于:https://my.oschina.net/lupeng/blog/370064

修改加密函数以支持二进制数据%%AES实现 =================================================== function [encrypted, iv_salt] = AES_Encrypt(plaintext, key) % 生成动态salt和iv,各16字节 salt = randi([0 255], 1, 16, 'uint8'); iv = randi([0 255], 1, 16, 'uint8'); iv_salt = [salt iv]; % 合并salt和iv输出(32字节) key = AES_KeyDerivation(key, 16, salt); % 传入动态salt cipher = javax.crypto.Cipher.getInstance('AES/CBC/PKCS5Padding'); cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, ... javax.crypto.spec.SecretKeySpec(key, 'AES'), ... javax.crypto.spec.IvParameterSpec(iv)); % 使用原始iv encrypted = cipher.doFinal(unicode2native(plaintext, 'UTF-8')); encrypted = typecast(encrypted, 'uint8'); encrypted = encrypted(:).'; end function decrypted = AES_Decrypt(ciphertext, key, iv_salt) try % 从合并参数分离salt和iv if length(iv_salt) ~= 32 error('IV/Salt参数长度错误,应为32字节'); end salt = iv_salt(1:16); iv = iv_salt(17:32); % 确保类型正确 salt = uint8(salt); iv = uint8(iv); ciphertext = uint8(ciphertext); % 密钥派生 key = AES_KeyDerivation(key, 16, salt); % 创建Java对象 cipher = javax.crypto.Cipher.getInstance('AES/CBC/PKCS5Padding'); keySpec = javax.crypto.spec.SecretKeySpec(key, 'AES'); ivSpec = javax.crypto.spec.IvParameterSpec(iv); % 初始化解密模式 cipher.init(javax.crypto.Cipher.DECRYPT_MODE, keySpec, ivSpec); % 执行解密 decryptedBytes = cipher.doFinal(ciphertext); decryptedBytes = typecast(decryptedBytes, 'uint8'); % 转换为字符串 decrypted = native2unicode(decryptedBytes, 'UTF-8'); catch ME if contains(ME.message, 'InvalidKeyException') errordlg('密钥错误,请检查加密密钥!','解密失败'); else rethrow(ME); end end end function derivedKey = AES_KeyDerivation(password, keyLength, salt) iterations = 1000000; % 将密码转换为Java char[] passwordChars = java.lang.String(password).toCharArray(); % 将salt转为Java byte[](MATLAB uint8转Java有符号byte) saltBytes = typecast(salt, 'int8'); % 构造密钥规范 spec = javax.crypto.spec.PBEKeySpec(... passwordChars, ... saltBytes, ... iterations, ... keyLength*8); % 生成密钥 factory = javax.crypto.SecretKeyFactory.getInstance('PBKDF2WithHmacSHA256'); tmpKey = factory.generateSecret(spec); derivedKey = typecast(tmpKey.getEncoded(), 'uint8'); end
03-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值