当前位置: 首页 > 知识库问答 >
问题:

服务器(Java-Cipher)和客户端(Javascript-CryptoJS)之间的AES

邹曦之
2023-03-14

我必须用JS制作一个应用程序,用AES编码一条消息,并通过AJAX将其传递给服务器。然后,服务器会启动并使用Java对消息进行解码。

我的问题是:如何在JS中加密消息,并使用AES在Java中解密它?知道java和js之间的通信已经通过Web服务建立

客户端,我使用Crypto JS库(http://code.google.com/p/crypto-js/)。服务器端我使用Java提供的Cipher类(我使用JavaPlay框架,但在这里没关系)。

我对密码学一无所知。我做了一整天的研究,但还是没能成功。

问题是用于加密和解密消息的密钥必须相同,我不知道如何做到这一点。

从我的搜索中,我了解到使用AES有不同的模式。默认情况下Java使用欧洲央行,密码JS使用CBC,这是一个问题,但通过告诉密码JS也使用欧洲央行模式,这似乎并不难解决。但是还有一个填充问题,似乎Java和CryptoJS中唯一可用的填充根本没有填充。但是当我在Java中使用NoPadd时,我得到了一个例外。

但是即使我设法解决了这个问题,最大的问题是密码JS生成的密钥和Java生成的密钥是不一样的。如果我用Java加密一条消息,结果总是一样的,用十六进制。但是在加密JS中,它是在Base64中,它永远不一样......

我知道这是由密钥生成造成的,这在Java和CryptoJS中是不一样的(然后进入了IV和Salt的概念,这对我来说是模糊的)。

共有2个答案

祁奇略
2023-03-14

我最近在这个问题上花了几天时间。我尝试了很多java和javascript方面的库。这个博客挽救了我的一天:http://watchitlater.com/blog/tag/aes/。

所以这是可以做到的!用胡言乱语就行了(https://github.com/mdp/gibberish-aes)javascript端是一个,java端是一个bouncycastle。

java端加密可能如下所示(参见上述博客):

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.spec.InvalidKeySpecException;
import java.util.Random;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import sun.misc.BASE64Encoder;


public class OpenSSLEncryption {

    private static final String CIPHER_ALG = "PBEWITHMD5AND256BITAES-CBC-OPENSSL";
    private static final Provider CIPHER_PROVIDER = new BouncyCastleProvider();
    private static final String PREFIX = "Salted__";
    private static final String UTF_8 = "UTF-8";
    private String password;
    private PBEKeySpec pbeSpec;
    private SecretKeyFactory keyFact;
    private Cipher cipher;
    private Random rand = new Random();
    private BASE64Encoder encoder = new BASE64Encoder();

    public OpenSSLEncryption(String password) throws NoSuchAlgorithmException, NoSuchPaddingException {
        this.password = password;
        pbeSpec = new PBEKeySpec(password.toCharArray());
        keyFact = SecretKeyFactory.getInstance(CIPHER_ALG, CIPHER_PROVIDER);
        cipher = Cipher.getInstance(CIPHER_ALG, CIPHER_PROVIDER);
    }  

    public synchronized String encrypt(String toEncrypt) throws InvalidKeySpecException, InvalidKeyException, InvalidAlgorithmParameterException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException, IOException {
        byte[] salt = new byte[8];
        rand.nextBytes(salt);
        PBEParameterSpec defParams = new PBEParameterSpec(salt, 0);
        cipher.init(Cipher.ENCRYPT_MODE, keyFact.generateSecret(pbeSpec), defParams);
        byte[] cipherText = cipher.doFinal(toEncrypt.getBytes(UTF_8));

        ByteArrayOutputStream baos = new ByteArrayOutputStream(cipherText.length + 16);
        baos.write(PREFIX.getBytes(UTF_8));
        baos.write(salt);
        baos.write(cipherText);
        baos.close();
        return encoder.encode(baos.toByteArray());
    }
}
马银龙
2023-03-14

不要在浏览器JS中进行加密;这不可能做到安全。

使用SSL。其目的是加密浏览器和服务器之间的通信

如果成本是你的问题,有免费的SSL证书。

 类似资料:
  • 问题内容: 我正在尝试在Java中的服务器和JavaScript客户端之间建立连接,但在客户端出现此错误: WebSocket与“ ws://127.0.0.1:4444 /”的连接失败:在收到握手响应之前,连接已关闭 由于可能从未调用该函数,因此它可能保持在OPENNING状态。该不会被调用。 有人可以让我知道这里出了什么问题吗? 服务器 服务器线程 游戏协议 客户 问题答案: 首先,您的两个代

  • 问题内容: 简而言之,我有一个独立的ES主实例和一个在我的Java应用程序中创建的客户端节点。如果在客户端节点之前启动了独立ES实例,则客户端节点会正确发现独立ES实例。 我面临的问题是-如果由于某种原因,客户端节点在独立ES实例之前启动,我会看到“ MasterNotDiscoveredException”,这也是可预期的。但是,即使启动独立的ES实例后,我仍然会看到相同的异常。我应该更改一些配

  • 问题内容: 我用Node.js运行一个简单的http服务器: 我的index.html文件: 现在,我想在我的index.html文件中打印服务器端变量:temp。但是我不知道该怎么做。 也许有人可以帮助我从服务器到客户端交换变量。 问题答案: 正如您可以在@WebServer的答案中看到的那样,节点中有多种模板引擎。 我想给你一个使用其中一个的例子-EJS: 首先安装它: server.js:

  • 我想在一些计算机之间建立点对点连接,这样用户就可以在没有外部服务器的情况下聊天和交换文件。我最初的想法如下: 我在服务器上制作了一个中央服务器插座,所有应用程序都可以连接到该插座。此ServerSocket跟踪已连接的套接字(客户端),并将新连接的客户端的IP和端口提供给所有其他客户端。每个客户端都会创建一个新的ServerSocket,所有客户端都可以连接到它。 换句话说:每个客户端都有一个Se

  • 问题内容: 我尝试使用以下代码从服务器到客户端发送文件和目录列表。服务器正在从客户端接收消息,但我不知道服务器是否没有发送回结果或客户端是否不接受结果。 服务器端: 问题答案: 据我所见,您在客户端上做的同时在服务器上做。从服务器发送的字符串中没有行尾字符,因此客户端将永远无法完成。执行outqw.println()或添加到要发送的内容的末尾。话虽这么说,很难用一堆注释掉的东西来浏览未格式化的代码

  • 问题内容: 我正在尝试在Java主机和android客户端之间设置双向身份验证SSL连接。不知道为什么它没有连接。以下是Android客户端应用和Java服务器的代码。 客户代码: 服务器代码: 我在服务器上遇到“没有共同的密码套件”错误。由于我不在SSL连接设置中。如果您发现错误或主要问题,请允许我提供帮助。 这是我用来创建证书和信任库的链接。我创建的Truststore和kestore在这里