java dofinal_java – 在AES解密时,给定Final Block未正确填...

首先,我会告诉我的主要目标是什么.我将使用AES加密客户端中的某些内容,然后使用RSA公钥加密重要的AES规范,并将AES加密数据和RSA加密AES规范发送到服务器.所以在服务器上,我将使用RSA私钥解密AES密钥规范,然后使用这些AES规范,我将解密AES加密数据.我通过测试加密和解密成功地使RSA部分工作.在实现RSa之前,我要使这个AES艺术工作.

对于客户端,我使用的是crypto-js

$("#submit").click(function() {

var salt = CryptoJS.lib.WordArray.random(16);

var iv = CryptoJS.lib.WordArray.random(16);

var pass = CryptoJS.lib.WordArray.random(16);

var message = "Test Message for encryption";

var key128Bits = CryptoJS.PBKDF2(pass, salt, { keySize: 128 });

var key128Bits10Iterations = CryptoJS.PBKDF2(pass, salt, { keySize: 128, iterations: 10 });

var encrypted = CryptoJS.AES.encrypt(message, key128Bits10Iterations, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });

var cipherData = encrypted.toString()+":"+salt.toString()+":"+iv.toString()+":"+pass.toString();

console.log(cipherData);

$.ajax({

url: 'encryption',

type: 'POST',

data: {

cipherData: cipherData

},

success: function(data) {

console.log(data);

},

failure: function(data) {

}

});

});

这是我在服务器端使用的代码

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

String encryptedData = request.getParameter("cipherData");

String data[] = encryptedData.split(":");

String encrypted = data[0];

String salt = data[1];

String iv = data[2];

String password = data[3];

byte[] saltBytes = hexStringToByteArray(salt);

byte[] ivBytes = hexStringToByteArray(iv);

IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);

SecretKeySpec sKey = null;

try {

sKey = (SecretKeySpec) generateKeyFromPassword(password, saltBytes);

} catch (GeneralSecurityException e) {

e.printStackTrace();

}

try {

System.out.println( decrypt( encrypted , sKey ,ivParameterSpec));

} catch (Exception e) {

e.printStackTrace();

}

}

public static SecretKey generateKeyFromPassword(String password, byte[] saltBytes) throws GeneralSecurityException {

KeySpec keySpec = new PBEKeySpec(password.toCharArray(), saltBytes, 10, 128);

SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

SecretKey secretKey = keyFactory.generateSecret(keySpec);

return new SecretKeySpec(secretKey.getEncoded(), "AES");

}

public static byte[] hexStringToByteArray(String s) {

int len = s.length();

byte[] data = new byte[len / 2];

for (int i = 0; i < len; i += 2) {

data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)

+ Character.digit(s.charAt(i+1), 16));

}

return data;

}

public static String decrypt(String encryptedData, SecretKeySpec sKey, IvParameterSpec ivParameterSpec) throws Exception {

Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");

c.init(Cipher.DECRYPT_MODE, sKey, ivParameterSpec);

byte[] decordedValue = Base64.decodeBase64(encryptedData);

byte[] decValue = c.doFinal(decordedValue);

String decryptedValue = new String(decValue);

return decryptedValue;

}

首先,我要确保服务器正在接收我正在发送的相同数据.所以我通过sysout对加密,salt,iv和密码进行了测试.它收到了相同的数据.但我得到了例外

byte[] decValue = c.doFinal(decordedValue);

javax.crypto.BadPaddingException: Given final block not properly padded

at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966)

at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)

at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436)

at javax.crypto.Cipher.doFinal(Cipher.java:2121)

at com.Encryption.decrypt(Encryption.java:95)

at com.Encryption.doPost(Encryption.java:60)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:644)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)

at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)

at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)

at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)

at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:136)

at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)

at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)

at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:526)

at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1078)

at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:655)

at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)

at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1566)

at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1523)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)

at java.lang.Thread.run(Thread.java:745)

你可以看到在Javascript方面,它是CryptoJS.pad.Pkcs7,在服务器端它是AES / CBC / PKCS5Padding,我已经做了一些搜索,发现它们都是相同的.我既不能将其更改为CryptoJS.pad.Pkcs5,也不能将AES / CBC / PKCS7Padding更改为Crypto-js库和Java inbuild库.

我也有以下想法.在javascript中,我使用随机盐并传递生成128位密钥.使用相同的salt并传递,我通过定义适当的迭代计数和密钥大小在Java中生成相同的密钥.为什么我必须通过再次生成相同的密钥来延长Java中的进程?我只需将密钥(encrypted.key),encrytedData(encrypted.toString())和Iv(encrypted.iv)发送到服务器并立即解密数据,而无需再次生成密钥.我是对的吗?我也试过这个,我得到“无效的AES密钥长度异常”.为了保持安全性,我将使用RSA公钥加密客户端的密钥和Iv.实现Syymmetric with Asymmetric的原因之一是由于RSA的加密数据量有限.但是如果我不能清除这个BadPaddingException,我就无法实现它.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值