加密导致错误时出现问题:
javax.crypto.IllegalBlockSizeException: data not block size aligned
at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(Unknown Source)
at javax.crypto.Cipher.doFinal(Cipher.java:2086)
at com.lcp.sso.logic.SsoCipher.encode(SsoCipher.java:89)
对象的构造函数:
public MyCipher() throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, UnsupportedEncodingException {
Security.addProvider(new BouncyCastleProvider());
KeyGenerator keyGen = KeyGenerator.getInstance("DESede", "BC");
keyGen.init(new SecureRandom());
SecretKey keySpec = keyGen.generateKey();
this.sharedKey = keySpec.getEncoded().toString();
this.encrypter = Cipher.getInstance("DESede/ECB/Nopadding", "BC");
this.encrypter.init(Cipher.ENCRYPT_MODE, keySpec);
this.decrypter = Cipher.getInstance("DESede/ECB/Nopadding", "BC");
this.decrypter.init(Cipher.DECRYPT_MODE, keySpec);
}
发生错误的方法:
public String encode(String arg_text) throws IllegalBlockSizeException, BadPaddingException {
byte[] encrypt = arg_text.getBytes();
if(encrypt.length % 8 != 0){ //not a multiple of 8
//create a new array with a size which is a multiple of 8
byte[] padded = new byte[encrypt.length + 8 - (encrypt.length % 8)];
//copy the old array into it
System.arraycopy(encrypt, 0, padded, 0, encrypt.length);
encrypt = padded;
}
byte[] b = Base64.encodeBase64URLSafe(encrypt);
return Base64.encodeBase64String(encrypter.doFinal(b));
}
在那里调用最后一个方法时会发生错误。我发誓我正在使它成为正确的块大小,在那里,通过空填充字节数组来确保它是8的倍数。我只是不知道出了什么问题!
我正在使用:
Eclipse版本:Juno Service Release 1
服务器:Localhost的Tomcat v7.0服务器(特别是7.0.32)
--- 编辑 ---
程序尚未运行,(编辑:是的!Muahahahaha!)但问题已解决。
对象的构造函数:
public MyCipher() throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, UnsupportedEncodingException, InvalidParameterSpecException, InvalidAlgorithmParameterException {
Security.addProvider(new BouncyCastleProvider());
KeyGenerator keyGen = KeyGenerator.getInstance("DES", "BC");
keyGen.init(new SecureRandom());
SecretKey keySpec = keyGen.generateKey();
this.sharedKey = new String( Base64.encodeBase64URLSafe( keySpec.getEncoded() ) );
this.encrypter = Cipher.getInstance("DES/CBC/PKCS5Padding", "BC");
this.encrypter.init(Cipher.ENCRYPT_MODE, keySpec);
AlgorithmParameters params = this.encrypter.getParameters();
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
IvParameterSpec ivSpec = new IvParameterSpec(iv);
this.sharedIV = new String( Base64.encodeBase64URLSafe( iv ) );
this.decrypter = Cipher.getInstance("DES/CBC/PKCS5Padding", "BC");
this.decrypter.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
}
加密方法是:
public String encode(String arg_text) throws IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
byte[] encrypt = arg_text.getBytes();
return new String( Base64.encodeBase64URLSafe(encrypter.doFinal(encrypt)), "US-ASCII");
}
现在正在努力加密和解密就好了。非常感谢你。
答案 0 :(得分:4)
某些方面的奇怪代码。由于您的代码不起作用的原因,您确保encrypt
的大小是8的倍数,但您正在尝试加密byte[] b = Base64.encodeBase64URLSafe(encrypt);
,这可能不是8的倍数。以下代码应该有效:
public String encode(String arg_text) throws IllegalBlockSizeException, BadPaddingException {
byte[] encrypt = arg_text.getBytes();
if(encrypt.length % 8 != 0){ //not a multiple of 8
//create a new array with a size which is a multiple of 8
byte[] padded = new byte[encrypt.length + 8 - (encrypt.length % 8)];
//copy the old array into it
System.arraycopy(encrypt, 0, padded, 0, encrypt.length);
encrypt = padded;
}
return new String(Base64.encodeBase64URLSafe(encrypter.doFinal(b)), "US-ASCII");
}
现在,有this.encrypter = Cipher.getInstance("DESede/ECB/Nopadding", "BC");
的地方你注意到字符串的“Nopadding”部分吗?好吧,代码执行你要求它做的...但是库可以为你做填充工作,你只需要告诉它。请尝试this.encrypter = Cipher.getInstance("DESede/ECB/PKCS5Padding", "BC");
,看看它是否有效。
但实际上,为什么要在ECB模式下使用3DES?除非原因是遗产(这在我看到的内容中不太可能),否则没有意义。我相信你需要阅读更多有关密码学的内容。