java - 我 block 填充,仍然得到 "data not block size aligned"

标签 java encryption bouncycastle

我在加密时遇到问题导致错误:

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));
}

错误发生在调用最后一个方法时。我发誓我正在使它成为正确的 block 大小,在那里,通过空填充字节数组以确保它是 8 的倍数。我只是不知道出了什么问题!

我正在使用:
Eclipse 版本:Juno Service Release 1
服务器:本地主机上的 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");
}

它现在可以很好地加密和解密。非常感谢。

最佳答案

某些方面的代码很奇怪。从为什么你的代码不起作用开始,你要确保 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"); 你注意到字符串的“N​​opadding”部分了吗?好吧,代码会按照您的要求执行...但是库可以为您完成填充工作,您只需要告诉它即可。试试 this.encrypter = Cipher.getInstance("DESede/ECB/PKCS5Padding", "BC"); 看看它是否有效。

但实际上,您为什么要在 ECB 模式下使用 3DES?除非原因是遗留的(从我在这里看到的情况来看这不太可能),否则它没有意义。我相信您需要阅读更多有关密码学的内容。

关于java - 我 block 填充,仍然得到 "data not block size aligned",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15147099/

相关文章:

java - PoolingClientConnectionManager中的 "per route basis"是什么意思?

CS50 Vigenere - 奇怪的图案

java - 如何在Java中正确使用RSASSA-PSS进行签名?

java - 使用 BouncyCaSTLe 进行 Pad block 损坏错误解码 Rijndael 256

java - <ui :debug/> tag not working in Facelets (JSF 2. 0)

java - 在这种情况下,如何使 spring 在使用泛型时注入(inject)正确的 bean?

java - 两个循环中的增长顺序

c# - 为 DSA 生成 40 个字符的指纹

encryption - 从 PHP 到 Go 的 Mcrypt

java - 为什么用充气城堡解密后会附加这些方形符号?