- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
首先,我将说明我的主要目标是什么。我将在客户端使用 AES 加密一些内容,然后使用 RSA 公钥加密重要的 AES 规范,并将 AES 加密数据和 RSA 加密 AES 规范发送到服务器。因此,在服务器上,我将使用 RSA 私钥解密 AES key 规范,然后使用这些 AES 规范,我将解密 AES 加密数据。我已经通过测试加密和解密成功地使 RSA 部分工作。在实现 RSa 之前,我必须让这个 AES 艺术工作。
对于客户端,我使用的是 crypto-js
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/pbkdf2.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/enc-base64-min.js"></script>
<script type="text/javascript" src="jquery-1.7.1.js"></script>
<script type="text/javascript">
$("#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) {
}
});
});
</script>
这是我在服务器端使用的代码
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 内置库定义。
我也有以下想法。在 javascript 中,我使用随机盐并传递生成 128 位 key 。使用相同的 salt 和 pass,我通过定义适当的迭代计数和 key 大小在 Java 中生成相同的 key 。为什么我必须通过再次生成相同的 key 来延长 Java 中的过程?我可以简单地将 key (encrypted.key)、encrytedData(encrypted.toString()) 和 Iv (encrypted.iv) 发送到服务器并立即解密数据,而无需再次生成 key 。我对这个..?我也试过这个,我得到“无效的 AES key 长度异常”。为了维护安全,我将使用 RSA 公钥在客户端对 key 和 Iv 进行加密。使用非对称实现对称的原因之一是由于 RSA 的加密数据大小有限。但是如果我不能清除这个 BadPaddingException,我就不能实现它。
最佳答案
既然你想使用 RSA 并且已经实现了它,就没有必要使用密码派生。创建随 secret 钥和随机 iv:
var key = CryptoJS.lib.WordArray.random(16); // 128bit
var iv = CryptoJS.lib.WordArray.random(16); // 128bit
var encrypted = CryptoJS.AES.encrypt(message, key, { iv: iv }); // CBC/PKCS#7 is default
然后你发送iv.toString(Crypto.enc.Base64)
, encrypted.ciphertext.toString(Crypto.enc.Base64)
和“RSAencrypt(key)”到服务器,对base64编码的iv和密文进行解码,对RSA密文进行解密得到AES key ,将它们组合起来解密密文。
您最初的问题可能出在您使用的尺寸上。 CryptoJS 有一个内部表示,每个字由 4 个字节组成。这就是为什么您需要除以 32 以获得 128 位散列的原因:
var key128Bits = CryptoJS.PBKDF2(pass, salt, { keySize: 128/32 });
另一方面,WordArray 仅适用于字节,这就是为什么要除以 8:
var key = CryptoJS.lib.WordArray.random(128/8);
关于java - 给定最终 block 在 AES 解密时未正确填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28263491/
我有一个 C# 应用程序调用 Java 网络服务来验证用户密码。我想让 C# 应用程序加密密码,然后让 Java Web 服务解密密码。我已经完成了 Java 端的代码(解密代码),但我无法找出 C#
我正在使用以下代码在使用 openssl 的 Windows 中使用 C 加密和解密二进制数据。如您所见,在这两个函数中,我都知道纯文本的大小。有什么方法可以在不知道纯文本大小的情况下解密消息? #i
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我有一个非常恼人的问题,Java中使用RSA算法对字符串进行不可靠的加密和解密。它似乎只能在大约 35% 的时间内工作,而且我不明白为什么它有时能工作,有时却不能。这是我写的一些测试代码,试图验证加密
我已经设法编写了用于文件加密/解密的函数。但它非常慢,尤其是随着文件大小的增加。例如几MB长的音频/视频文件 我几乎浏览了所有帖子来改进它,并尝试更改算法。如果有任何更改可以帮助我提高性能,请帮助我。
我正在尝试让我的转置密码发挥作用。 每当我将加密方法得到的密文输入解密方法时,我应该得到原始的明文......但事实并非如此...... 我做错了什么? 感谢您的帮助! public String E
我正在使用密码来加密和解密消息: public String encrypt(String string) throws InvalidKeyException, IllegalBlockSizeEx
我有一个在 MySQL 中存储数据的 spring-mvc 堆栈。其中一些数据需要保护,所以我想我应该加密它。由于我以后可能需要使用这些数据(信用卡、SSN 等),所以我需要对其进行解密。我认为这排除
作为一名SEOER,都想了解百度算法,通过算法原理来找到捷径的优化方案,那么今天我把研究多年的百度算法原理解密给大家,可能不是最好的,但是我可以给大家保证,这些都是非常实际的。希望给SEOER带来一
我试图找到一种技术来加密和解密程序中的文件,而无需将密码硬编码到程序中,也无需向用户询问密码。 如果我也可以从我正在编写的另一个程序中解密文件,那就太好了。 到目前为止,我还没有多少运气找到一种看起来
有没有一种方法可以使用作为字符串参数传递给程序的私钥而不是使用存储在机器上的证书来解密 PowerShell 中的 RSA?欢迎任何帮助,我的代码如下。 Function Decrypt-Asymme
通过问题Is it possible to use the Grails Jasypt plugin outside the GORM layer for simple String encrypti
我需要解密/加密我的域类中的几列,并且正在寻找有关如何做的信息。我已经找到了jasypt加密插件,但不幸的是它似乎与Grails 2.4不兼容。 我可能可以将一些东西拼凑在一起,但是想要确保Im遵循最
我需要有关声音文件加密/解密的帮助。我想在存储这个声音文件时加密一个声音文件,并在播放这个文件时解密它。我阅读了有关 java 中的加密/解密以及 java 中可用于此的大量示例代码。但这些程序不适用
我很感兴趣是否可以使用 Excel Visual Basic 和某些加密服务提供程序进行字符串加密/解密。 我找到了一个演练 Encrypting and Decrypting Strings in
我们正在使用加密/解密和UIIMAGE。如果我们在不保存到iphone画廊的情况下进行加密和解密以及UIIMAge,则可以正常工作,但是,如果我们进行加密,保存到画廊,将(加密的图像)加载到应用程序中
我正在做一个像这样的简单程序: package rsaexample; import java.io.*; import java.math.BigInteger; import java.secur
我发现这段代码返回给定字符串的校验和。 public static String getChecksum(String md5) { int counter = 0; while (c
我在 Java SE 和 Android 项目上使用相同的代码。在 Java 和 Android 中运行的应用程序连接到相同的 MQTT 代理并交换消息。消息使用 AES 进行加密/解密。我对 Jav
我想在 openssl/libcrypto 中使用 RSA 加密/解密一个长文件(我知道 AES 更好,但这只是为了比较)。我将输入文件分成大小为 numBlocks = inputFileLengt
我是一名优秀的程序员,十分优秀!