Java base64编码问题

Java base64编码问题,java,javascript,base64,aes,Java,Javascript,Base64,Aes,我使用AES加密和解密我的密码。我试图实现的是,我需要以cookie的形式将加密密码存储在客户端,然后当客户端再次登录到我的网站时,我需要从客户端获取加密密码并解密,以对照客户端提供的未加密密码进行检查。我面临的问题是,在加密时,我使用java中的BASE64.encodeString()将加密密码的字节数组转换为字符串,以便将其传递给客户端。但当我从客户端(即cookie)获取相同的字符串并尝试对其进行解密时,会出现填充错误,即javax.crypto.illegalBlockSizeExce

我使用AES加密和解密我的密码。我试图实现的是,我需要以cookie的形式将加密密码存储在客户端,然后当客户端再次登录到我的网站时,我需要从客户端获取加密密码并解密,以对照客户端提供的未加密密码进行检查。我面临的问题是,在加密时,我使用java中的BASE64.encodeString()将加密密码的字节数组转换为字符串,以便将其传递给客户端。但当我从客户端(即cookie)获取相同的字符串并尝试对其进行解密时,会出现填充错误,即javax.crypto.illegalBlockSizeException:使用填充密码解密时,输入长度必须是16的倍数

为什么会这样

加密代码:

  Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivspec);
            byte[] plainBytes = Data.getBytes(UNICODE_FORMAT);
            byte[] encrypted = cipher.doFinal(plainBytes);
            String encryption = Base64.encodeBase64String(encrypted);
            return encryption;
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivspec);
        byte[] decryptval = Base64.decodeBase64(encryptedData);
        byte[] decrypted = cipher.doFinal(decryptval);
        return new String(decrypted);
解密代码:

  Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivspec);
            byte[] plainBytes = Data.getBytes(UNICODE_FORMAT);
            byte[] encrypted = cipher.doFinal(plainBytes);
            String encryption = Base64.encodeBase64String(encrypted);
            return encryption;
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivspec);
        byte[] decryptval = Base64.decodeBase64(encryptedData);
        byte[] decrypted = cipher.doFinal(decryptval);
        return new String(decrypted);

错误是因为我将加密字符串传递给js以存储在cookie中吗。??JS会摆弄Base64编码的字符串吗?

尝试在加密时使用以下方法将字节转换为字符串-

public static String bytesToString(byte[] bytes) {
    HexBinaryAdapter adapter = new HexBinaryAdapter();
    String s = adapter.marshal(bytes);
    return s;
}
所以不是-

String encryption = Base64.encodeBase64String(encrypted);
使用

类似地,在解密过程中使用此方法-

public static byte[] hexToBytes(String hexString) {
    HexBinaryAdapter adapter = new HexBinaryAdapter();
    byte[] bytes = adapter.unmarshal(hexString);
    return bytes;
}
就是-

byte[] decryptval = hexToBytes(encryptedData);

我强烈建议不要使用密码来存储/传输密码

哈希函数是一个更安全的想法。密码和散列的区别在于,密码是可逆的,而散列是单向的(明文->散列文本)。在服务器上以a)明文或b)加密的形式存储用户密码在安全性方面是一个很大的禁忌

另一方面,散列不能反转;(至少在理论上)

使用
MessageDigest
类同样可以轻松地完成简单的哈希

获取散列非常简单:

Message Digest md = MessageDigest.getInstance("MD5");
md.digest(input.getBytes());

然后,客户端可以散列明文密码以发送到服务器。然后,服务器可以比较哈希值进行身份验证,并将会话令牌返回给用户,用户可以在会话的剩余时间使用会话令牌,而无需到处传输密码。

如果黑客读取base64字符串并连接到应用程序,假装是真正的用户,该怎么办?我为每次运行分配不同的令牌加密算法的一部分。。还有一个序列标识符,用于检查是否有违反安全性的行为。它给出了一个illegalArgumentExeption:hexBinary的长度必须为偶数。。我检查了传递给js的值和从js接收到的值是否相同。加密密钥的长度应该是16。我正在使用密钥生成器,它将密钥生成为字节数组。。如果我打印那个字节数组,它的长度是11个字符。我也在使用SecretKeySpec,这是在初始化密码时使用的,正如你在我的加密代码中看到的那样,我需要我的密钥以字节数组的形式存在。key key key=new SecretKeySpec(“abcdefghijklmnop”).getBytes(“UTF-8”),algorithm);//你能试一下这样的方法吗,检查键字符串,长度为16个字符@sudhanshu。。我通过JS发送的数据也有问题。。我解决了这个问题,然后这个解决方案很好地工作了。。谢谢当您只想检查密码的有效性时,哈希是好的。但在某些情况下,可能需要对存储的密码进行解密,比如在文件中存储一个db密码(加密),并希望对其进行解密并将其用于连接。