Java IllegalBlocksizeException-如何使用Base64解决
我在下面的代码中遇到了一些问题-我似乎得到了一个非法的BlockSizeException,并且不确定我在这里可能做得不正确是什么?有没有可能得到一些建议/建议 谢谢Java IllegalBlocksizeException-如何使用Base64解决,java,security,cryptography,aes,Java,Security,Cryptography,Aes,我在下面的代码中遇到了一些问题-我似乎得到了一个非法的BlockSizeException,并且不确定我在这里可能做得不正确是什么?有没有可能得到一些建议/建议 谢谢 public class Encryption { private SecretKeyFactory factory; private SecretKey tmp; private SecretKey secret; private Cipher ci
public class Encryption
{
private SecretKeyFactory factory;
private SecretKey tmp;
private SecretKey secret;
private Cipher cipher;
private byte[] iv;
private byte[] cipherText;
private final KeySpec spec = new PBEKeySpec("somepassword".toCharArray(), SALT, 65536, 256);
private static final byte[] SALT = {(byte)0xc3, (byte)0x23, (byte)0x71, (byte)0x1c, (byte)0x2e, (byte)0xc2, (byte)0xee, (byte)0x77};
public Encryption()
{
try
{
factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
tmp = factory.generateSecret(spec);
secret = new SecretKeySpec(tmp.getEncoded(), "AES");
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
iv = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
}
catch (Exception e)
{
e.printStackTrace();
}
}
public String encrypt(String valueToEncrypt) throws Exception
{
cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(iv));
cipherText = cipher.doFinal(Base64.decodeBase64(valueToEncrypt.getBytes()));
return Base64.encodeBase64String(cipherText);
}
public String decrypt(String encryptedValueToDecrypt) throws Exception
{
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
return new String(cipher.doFinal(new Base64().encode(encryptedValueToDecrypt.getBytes())));
}
public static void main(String[] args ) throws Exception
{
Encryption manager = new Encryption();
String encrypted = manager.encrypt("this is a string which i would like to encrypt");
System.out.println(encrypted);
String decrypted = manager.decrypt(encrypted);
System.out.println(decrypted);
System.out.println(encrypted.equals(decrypted));
}
}
例外情况如下
Exception in thread "main" javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:750)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
at javax.crypto.Cipher.doFinal(Cipher.java:2087)
at encrypt.Encryption.decrypt(Encryption.java:52)
at encrypt.Encryption.main(Encryption.java:60)
在解密之前,您可能应该先对
encryptedValueToDecrypt
进行base64解码。在解密之前,您可能应该先对encryptedValueToDecrypt
进行base64解码。从功能角度来看,这是开始实施加密算法的唯一方法(请记住,一个工作代码不一定是安全的,应该有很多这样的想法),它是增量的:首先使用固定密钥尝试原始AES,然后添加由PBKDF2生成的密钥,然后再添加Base64。后者只是一个编码工具,应该是过程中最简单的部分
但是让我们看一下代码: 1.如果您的目标是从密码生成密钥,那么初始化似乎很好。 2.在解密过程中,这一行不起作用:
cipherText = cipher.doFinal(Base64.decodeBase64(valueToEncrypt.getBytes()));
valueToEncrypt是一个可读字符串,但您正在尝试对其进行解密。由于它只有小写字母和空格,因此可能不会触发错误,但您正在尝试对未进行base64编码的内容进行base64解码。尝试以下操作更有意义:
cipherText = cipher.doFinal(valueToEncrypt.getBytes());
然后可以对密文进行base64编码
对于解密部分,按相反顺序撤消加密中的操作。如果先加密,然后进行base64编码,则base64先解码,然后解密
最后一个建议是:考虑模块化。在一行中编码,在另一行中加密,因此如果要删除或添加层,只需在一行中切换注释。从功能角度来看,这是开始实施加密算法的唯一方法(请记住,一个工作代码不一定是安全的,应该有很多这样的想法),它是增量的:首先使用固定密钥尝试原始AES,然后添加由PBKDF2生成的密钥,然后再添加Base64。后者只是一个编码工具,应该是过程中最简单的部分
但是让我们看一下代码: 1.如果您的目标是从密码生成密钥,那么初始化似乎很好。 2.在解密过程中,这一行不起作用:
cipherText = cipher.doFinal(Base64.decodeBase64(valueToEncrypt.getBytes()));
valueToEncrypt是一个可读字符串,但您正在尝试对其进行解密。由于它只有小写字母和空格,因此可能不会触发错误,但您正在尝试对未进行base64编码的内容进行base64解码。尝试以下操作更有意义:
cipherText = cipher.doFinal(valueToEncrypt.getBytes());
然后可以对密文进行base64编码
对于解密部分,按相反顺序撤消加密中的操作。如果先加密,然后进行base64编码,则base64先解码,然后解密
最后建议:考虑模块化。在一行中编码,在另一行中加密,因此如果要删除或添加层,只需在一行中切换注释。您已反转了base-64编码和解码操作。base-64将原始字节转换为可打印文本。您可以对加密的输出进行编码n操作使其可打印。但是,在尝试解密之前,您需要对该文本进行base‑64–解码
decrypt()
方法的这一部分导致了以下问题:
cipher.doFinal(new Base64().encode(encryptedValueToDecrypt.getBytes()))
这应该是:
cipher.doFinal(Base64.decodeBase64(encryptedValueToDecrypt.getBytes()))
询问“指针”非常开放。我能给你的最好建议是:不要自己编写代码。选择一个提供更高级别API的包,选择高安全性算法并根据最佳实践应用它们。你不知道自己在做什么,也无法编写安全代码。但是使用高质量的开源库帮助您开始了解有关加密的更多信息。您已经反转了base-64编码和解码操作。base-64获取原始字节并将其转换为可打印文本。您可以对加密操作的输出进行编码以使其可打印。但是,在尝试解密之前,您需要对该文本进行base-64解码
decrypt()
方法的这一部分导致了以下问题:
cipher.doFinal(new Base64().encode(encryptedValueToDecrypt.getBytes()))
这应该是:
cipher.doFinal(Base64.decodeBase64(encryptedValueToDecrypt.getBytes()))
询问“指针”非常开放。我能给你的最好建议是:不要自己编写代码。选择一个提供更高级别API的包,选择高安全性算法并根据最佳实践应用它们。你不知道自己在做什么,也无法编写安全代码。但是使用高质量的开源库帮助您开始了解有关加密的更多信息。我不认为base64是您问题的根源,但是您可以将堆栈跟踪添加到问题中吗?(或者,至少指定您在哪一行获得问题)。Hi Sergio-stack trace Added我不认为base64是您问题的根源,但是您可以将堆栈跟踪添加到问题中吗?(或者,至少指定您在哪一行获得问题).Hi Sergio-stack trace addedHaving看了一下我将在这里使用AES的bouncy castle实现-感谢您的支持help@Biscuit128这个网站并不是真的推荐图书馆,但我也会告诉你一些功能。BouncyCastle很好,因为它很全面,而且是由知识渊博的人编写的,但它很大而且是低级的,这使得它本身就更难使用。除此之外,文档很糟糕。Apache Shiro更高级,使用更具指导性,更易于使用。@128域名已经改变了,我将在这里使用AES的bouncy castle实现-感谢您的支持help@Biscuit128这个网站不是关于推荐图书馆,但我也会向您介绍一些功能。BouncyCastle很好,因为它是全面的,由知识渊博的人编写,但它又大又低,因此它是固有的