Java中的TripleDES加密错误 [英] TripleDES encryption error in java

查看:138
本文介绍了Java中的TripleDES加密错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在关注本教程使用3DES加密,我需要对密码设置进行一些更改,所以这是我的代码:

I'm following this tutorial to use 3DES encryption, and i needed to make some changes in cipher settings, so here's my code:

public class TripleDES {

public static int MAX_KEY_LENGTH = DESedeKeySpec.DES_EDE_KEY_LEN;
private static String ENCRYPTION_KEY_TYPE = "DESede";
private static String ENCRYPTION_ALGORITHM = "DESede/ECB/PKCS7Padding";
private final SecretKeySpec keySpec;
private final static String LOG = "TripleDES";

public TripleDES(String passphrase) {
    byte[] key;
    try {
        // get bytes representation of the password
        key = passphrase.getBytes("UTF8");
    } catch (UnsupportedEncodingException e) {
        throw new IllegalArgumentException(e);
    }

    key = padKeyToLength(key, MAX_KEY_LENGTH);
    key = addParity(key);
    keySpec = new SecretKeySpec(key, ENCRYPTION_KEY_TYPE);
}

// !!! - see post below
private byte[] padKeyToLength(byte[] key, int len) {
    byte[] newKey = new byte[len];
    System.arraycopy(key, 0, newKey, 0, Math.min(key.length, len));
    return newKey;
}

// standard stuff
public byte[] encrypt(String message) throws GeneralSecurityException, UnsupportedEncodingException {
    byte[] unencrypted = message.getBytes("UTF8");
    return doCipher(unencrypted, Cipher.ENCRYPT_MODE);
}

public byte[] decrypt(byte[] encrypted) throws GeneralSecurityException {
    return doCipher(encrypted, Cipher.DECRYPT_MODE);
}

private byte[] doCipher(byte[] original, int mode)
        throws GeneralSecurityException {
    Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM);
    // IV = 0 is yet another issue, we'll ignore it here
    // IvParameterSpec iv = new IvParameterSpec(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 });
    cipher.init(mode, keySpec); //, iv);
    return cipher.doFinal(original);
}

// Takes a 7-byte quantity and returns a valid 8-byte DES key.
// The input and output bytes are big-endian, where the most significant
// byte is in element 0.
public static byte[] addParity(byte[] in) {
    byte[] result = new byte[8];

    // Keeps track of the bit position in the result
    int resultIx = 1;

    // Used to keep track of the number of 1 bits in each 7-bit chunk
    int bitCount = 0;

    // Process each of the 56 bits
    for (int i = 0; i < 56; i++) {
        // Get the bit at bit position i
        boolean bit = (in[6 - i / 8] & (1 << (i % 8))) > 0;

        // If set, set the corresponding bit in the result
        if (bit) {
            result[7 - resultIx / 8] |= (1 << (resultIx % 8)) & 0xFF;
            bitCount++;
        }

        // Set the parity bit after every 7 bits
        if ((i + 1) % 7 == 0) {
            if (bitCount % 2 == 0) {
                // Set low-order bit (parity bit) if bit count is even
                result[7 - resultIx / 8] |= 1;
            }
            resultIx++;
            bitCount = 0;
        }
        resultIx++;
    }

    Log.d(LOG, "result: " + result);
    return result;
}
}

但是我在此行上收到InvalidKeyException:

But i'm getting InvalidKeyException on this line:

cipher.init(mode, keySpec);

LogCat:

W/System.err(758): java.security.InvalidKeyException: src.length=8 srcPos=8 dst.length=8 dstPos=0 length=8
W/System.err(758):  at org.bouncycastle.jce.provider.JCEBlockCipher.engineInit(JCEBlockCipher.java:584)
W/System.err(758):  at org.bouncycastle.jce.provider.JCEBlockCipher.engineInit(JCEBlockCipher.java:631)
W/System.err(758):  at javax.crypto.Cipher.init(Cipher.java:511)
W/System.err(758):  at javax.crypto.Cipher.init(Cipher.java:471)

我是新手,所以我可能忽略了一些东西,但我找不到它.任何帮助表示赞赏...

I'm new on encrytion so i probably overlook something but i cannot find what it is. Any help is appreciated...

推荐答案

我已经通过更改以下行找到了解决方案:

I've found solution by changing these lines:

try {
    // get bytes representation of the password
    key = passphrase.getBytes("UTF8");
} catch (UnsupportedEncodingException e) {
    throw new IllegalArgumentException(e);
}

key = padKeyToLength(key, MAX_KEY_LENGTH);
key = addParity(key);
keySpec = new SecretKeySpec(key, ENCRYPTION_KEY_TYPE);

进入这些:

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
byte[] keyBytes = GetKeyAsBytes(key);
keySpec = new SecretKeySpec(keyBytes, "DESede");

而GetKeyAsBytes方法是这样的:

while GetKeyAsBytes method is this:

public byte[] GetKeyAsBytes(String key) {
    byte[] keyBytes = new byte[24]; // a Triple DES key is a byte[24] array

    for (int i = 0; i < key.length() && i < keyBytes.length; i++) 
        keyBytes[i] = (byte) key.charAt(i);

    return keyBytes;
}

这篇关于Java中的TripleDES加密错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆