首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在javax.crypto中获取填充异常

在javax.crypto中获取填充异常
EN

Stack Overflow用户
提问于 2011-07-08 14:08:10
回答 2查看 2.3K关注 0票数 0

我正在尝试编写一个密码java测试类,它用BouncyCastle加密和解密字符串密码。main()非常简单,我执行encryptPass()decryptPass(),然后查看控制台跟踪。

问题是,当它试图解密时,我得到了一个填充异常:

代码语言:javascript
复制
javax.crypto.BadPaddingException: pad block corrupted
    at org.bouncycastle.jce.provider.JCEBlockCipher.engineDoFinal(Unknown Source)
    at javax.crypto.Cipher.doFinal(DashoA13*..)
    at com.kiengi.crypto.Crypto.decryptPass(Crypto.java:79)

我的代码是Crypto类的以下代码:

代码语言:javascript
复制
// password to be crypted
public String pass = "password_go_here";

// key for encrypt pass
public String passKey = generateRandomKey(); // generation clef 16 caractere [a-zA-Z0-9]

// Encrypted pass
public String cryptedPass;

public final Logger logger = Logger.getLogger(this.getClass());

private final static byte[] IV_BYTES = new byte[] { 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
        0x00, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };

public Crypto() {
    super();
}

public void encryptPass(){

    Security.addProvider(new BouncyCastleProvider());
    IvParameterSpec _ivSpec = new IvParameterSpec(IV_BYTES);

    try{
        KeyGenerator _keygen = KeyGenerator.getInstance("AES");
        _keygen.init(new SecureRandom(passKey.getBytes()));
        SecretKey _key = _keygen.generateKey();
        logger.trace("Secret key generated");

        Cipher _cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
        _cipher.init(Cipher.ENCRYPT_MODE, _key, _ivSpec);

        cryptedPass = asHex(_cipher.doFinal(pass.getBytes("UTF-8")));


        logger.trace("Encrypted pass : "+cryptedPass);


    }catch (Exception e) {
        logger.warn("encrypt failed");
        e.printStackTrace();
    }
}

public void decryptPass() {
    byte[] _passKey = passKey.getBytes();
    byte[] _cryptedPass = hexFromString(cryptedPass);

    Security.addProvider(new BouncyCastleProvider());   
    IvParameterSpec _ivSpec = new IvParameterSpec(IV_BYTES);

    try {           
        KeyGenerator _keygen = KeyGenerator.getInstance("AES");
        _keygen.init(new SecureRandom(_passKey));
        SecretKey _key = _keygen.generateKey();
        logger.trace("Secret key generated");

        Cipher _cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
        _cipher.init(Cipher.DECRYPT_MODE, _key, _ivSpec);

        String _pass = new String(_cipher.doFinal(_cryptedPass), "UTF-8");

        logger.trace("Decrypted pass : "+_pass);

    } catch (Exception e) {
        logger.warn("decrypt failed");
        e.printStackTrace();
    }

}

private int fromDigit(char ch) {
    if ((ch >= '0') && (ch <= '9')) {
        return ch - '0';
    } else if ((ch >= 'A') && (ch <= 'F')) {
        return ch + 10 - 'A';
    } else if ((ch >= 'a') && (ch <= 'f')) {
        return ch + 10 - 'a';
    } else {
        throw new IllegalArgumentException(String.format(
                "Invalid hex character 0x%04x", 0xff & ch));
    }
}

private byte[] hexFromString(String hex) {
    final byte[] buf = new byte[hex.length() / 2];
    for (int i = 0, j = 0; i < hex.length(); i += 2) {
        buf[j++] = (byte) (fromDigit(hex.charAt(i)) << 4 | fromDigit(hex
                .charAt(i + 1)));
    }
    return buf;
}

private static String asHex(byte buf[]) {
    final Formatter formatter = new Formatter(new StringBuffer());
    for (int i = 0; i < buf.length; i++) {
        formatter.format("%02x", 0xff & buf[i]);
    }
    return formatter.toString();
}

private String generateRandomKey() {
    String _chars = "abcdefABCDEF1234567890";
    StringBuffer _pass = new StringBuffer();
    for (int x = 0; x < 32; x++) {
        int i = (int) Math.floor(Math.random() * (_chars.length() - 1));
        _pass.append(_chars.charAt(i));
    }
    return _pass.toString();
}

有人知道这个例外是什么意思吗?

EN

回答 2

Stack Overflow用户

发布于 2011-07-09 13:09:53

这段代码有一个bug。它假定new SecureRandom(passKey.getBytes())只使用构造函数中提供的字节初始化SecureRandom实例。这是错误的。构造函数中的数据将补充SecureRandom使用的任何熵源,而不是替换它们。

您需要使用正确的基于密码的加密(PBE)方案。

票数 0
EN

Stack Overflow用户

发布于 2011-07-10 16:17:27

此异常意味着填充块已损坏。您使用16B块的PKCS#7填充。在这个示例中,您的输出也是16B。因此,应该始终添加值为0x10的16字节块。

填充由于解密损坏而损坏。您的SecureRandom实现添加了自己的熵并生成错误的解密密钥。这个SecureRandom构造函数使用注册了SecureRandom实现的第一个提供程序的第一个PRNG算法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6625642

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档