【问题标题】:Data not block size aligned in codenameone BouncyCastle (No Padding)数据未在代号中对齐 BouncyCastle 的块大小(无填充)
【发布时间】:2016-07-22 12:17:04
【问题描述】:

我正在尝试使用代号为 BouncyCastle 的库加密 ISO-0 pinblock。 我用来实现这一点的方法如下:

private static byte[] performEncrypt(byte[] key, String plainText, boolean padding) {
    byte[] ptBytes = plainText.getBytes();

    BufferedBlockCipher cipher;
    if (padding) {
        cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new DESedeEngine()));
    } else {
        cipher = new BufferedBlockCipher(new CBCBlockCipher(new DESedeEngine()));
    }
    cipher.init(true, new KeyParameter(key));
    byte[] rv = new byte[cipher.getOutputSize(ptBytes.length)];
    int oLen = cipher.processBytes(ptBytes, 0, ptBytes.length, rv, 0);
    try {
        cipher.doFinal(rv, oLen);
    } catch (CryptoException ce) {
        LoggingUtil.error(TAG, ce, "Unexpected Exception");
    }
    return rv;
}

private static String createIso0PinBlock(String pin, String number) {
    ...
}

private static String getPaddedData(String data, byte padCharacter) {
    String paddedData = ByteUtil.pad(data, (char) padCharacter, 8).toString();
    return paddedData;
}

public static String createPinBlockAndEncrypt(String pin, String number) {
    LoggingUtil.debug("SecurityUtil", "CREAT PIN BLOCK AND ENCRYPT.. PIN: " + pin + " NUMBER: " + number);
    String pb = createIso0PinBlock(pin, number.substring(0, number.length() - 1));
    LoggingUtil.debug("SecurityUtil", "PINBLOCK: " + pb);
    String padded = getPaddedData(pb, (byte) 0x00);
    LoggingUtil.debug("SecurityUtil", "PADDED: " + padded);
    byte[] encrypted = performEncrypt(Hex.decode(KEY.getBytes()), new String(ByteUtil.hex2byte(padded)), false);
    return ByteUtil.byte2hex(encrypted);
}

ByteUtil:

public static StringBuilder pad(String data, char padCharacter, int multiplier) {
    StringBuilder text = new StringBuilder();
    text.append(data);
    while (text.length() % multiplier != 0) {
        text.append(padCharacter);
    }
    return text;
}

举个例子日志输出:

[SecurityUtil] CREAT PIN BLOCK AND ENCRYPT.. PIN: 2255 NUMBER: 6284734104205417486
[SecurityUtil] PINBLOCK: 042214FBDFABE8B7
[SecurityUtil] PADDED: 042214FBDFABE8B7

当我通过 public static void main 方法运行它时,它按预期工作,但是,当我通过 Codenameone 为 Android 构建它时,我在 logcat 中收到以下错误:

org.bouncycastle.crypto.DataLengthException: data not block size aligned
org.bouncycastle.crypto.BufferedBlockCipher.doFinal(BufferedBlockCipher.java:275)

尽管带衬垫的 pinblock 长度为 16(8 的倍数)。

我们将不胜感激有关此问题的任何帮助。

【问题讨论】:

    标签: java android encryption bouncycastle codenameone


    【解决方案1】:

    加密适用于二进制数据,而您的密码块是二进制,因此请保持这种状态。

    调用performEncrypt(..) 时,您将十六进制编码的pinblock 转换为带有new String(ByteUtil.hex2byte(padded)) 的字符串,并在performEncrypt(...) 中将其转换为带有byte[] ptBytes = plainText.getBytes(); 的字节数组。这样做的问题是,并非所有字节序列都可以通过字符串正确地来回映射,您最终可能会得到不同的数据甚至不同的长度等。take a look here

    将您的签名performEncrypt(..)更改为:

    private static byte[] performEncrypt(byte[] key, byte[] plainText, boolean padding) {
    

    并避免完全通过字符串进行转换。

    【讨论】:

    • 很好的答案。我会避免在 Codename One 中将字符串用于二进制数据,因为我们将字符串映射到本机字符串,例如在 iOS 上,它们在某些极端情况下可能会有轻微的行为差异。例如。我们在集成 zip 支持时遇到了问题codenameone.com/blog/zip-and-toast.html
    猜你喜欢
    • 1970-01-01
    • 2020-07-26
    • 2011-09-26
    • 2011-05-02
    • 2016-09-18
    • 2013-11-18
    • 1970-01-01
    • 2020-04-07
    • 1970-01-01
    相关资源
    最近更新 更多