为什么我似乎无法生成相同的基于密码的加密密钥?

时间:2011-11-11 21:42:46

标签: java encryption secret-key

我正在研究一些Java软件,它需要使用两个独立的软件加密和解密网络连接两端的信息。为了简化这一点,我有一个类Cryptographer,它处理数据加密。截至目前,Controller(连接的一端)和Agent(另一端)都使用此类根据两个程序之间共享的密码生成SecretKey。

密钥是在Cryptographer类的这个函数中生成的:

public SecretKey generateKey(String key) {
    this._paramSpec = new PBEParameterSpec(this.SALT, this.ITERATION_COUNT);
    PBEKeySpec spec = new PBEKeySpec(key.toCharArray());
    SecretKeyFactory fac = null;
    try {
        fac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
    } catch (NoSuchAlgorithmException ex) {
        ex.printStackTrace();
        System.err.println("[ERR] Cryptographer could not create a SecretKeyFactory due to an unsupported algorithm.");
    }
    try {
        if (fac == null)
            return null;
        return fac.generateSecret(spec);
    } catch (InvalidKeySpecException ex) {
        System.err.println("[ERR] Cryptographer could not generate a SecretKey due to an invalid Key Specification.");
        ex.printStackTrace();
        return null;
    }
}

加密本身发生在加密函数中:

public byte[] encrypt(byte[] message) {
    try {
        this._cipher.init(Cipher.ENCRYPT_MODE, this._key, this._paramSpec);
    } catch (InvalidKeyException ex) {
        System.err.println("[ERR] Cryptographer could not encrypt a message because the provided key is invalid.");
        ex.printStackTrace();
        return new byte[0];
    } catch (InvalidAlgorithmParameterException ex) {
        System.err.println("[ERR] Cryptographer could not encrypt a message because the parameters are invalid.");
        ex.printStackTrace();
        return new byte[0];
    }
    try {
        return this._cipher.doFinal(message);
    } catch (IllegalBlockSizeException ex) {
        System.err.println("[ERR] Cryptographer could not encrypt a message due to an illegal block size.");
        ex.printStackTrace();
        return new byte[0];
    } catch (BadPaddingException ex) {
        System.err.println("[ERR] Cryptographer could not encrypt a message due to bad padding.");
        ex.printStackTrace();
        return new byte[0];
    }
}

它由解密函数解密:

public byte[] decrypt(byte[] message) {
    try {
        this._cipher.init(Cipher.DECRYPT_MODE, this._key, this._paramSpec);
    } catch (InvalidKeyException ex) {
        System.err.println("[ERR] Cryptographer could not decrypt a message because the provided key is invalid.");
        return new byte[0];
    } catch (InvalidAlgorithmParameterException ex) {
        System.err.println("[ERR] Cryptographer could not decrypt a message because the parameters are invalid.");
    }
    try {
        return this._cipher.doFinal(message);
    } catch (IllegalBlockSizeException ex) {
        System.err.println("[ERR] Cryptographer could not decrypt a message due to an illegal block size.");
        return new byte[0];
    } catch (BadPaddingException ex) {
        System.err.println("[ERR] Cryptographer could not decrypt a message due to bad padding.");
        return new byte[0];
    }
}

加密似乎工作正常,但是当我尝试解密接收端的序列化对象时,会抛出InvalidKeyException。比较在Controller和Agent上独立生成的密钥表明,尽管它们来自相同的密码,但它们不会生成相同的密钥。

现在,我不熟悉Java加密,所以我完全有可能在这里做错了。似乎有一个随机因素,我错过了。目标是让连接的每一侧从相同的密码生成相同的密钥。那么我有什么事情显然是错的吗?如果您需要查看更多代码,请告诉我们。我很乐意发布它。

1 个答案:

答案 0 :(得分:0)

抛出的InvalidKeyException向我表明我会查看密钥在接收端的使用方式。您将它存储在数据库或文件中吗?您确定它与用于加密数据的编码相同吗?