【问题标题】:How do I encrypt in Python and decrypt in Java?如何在 Python 中加密并在 Java 中解密?
【发布时间】:2012-05-03 23:32:02
【问题描述】:

我正在尝试加密 Python 程序中的一些数据并将其保存,然后在 Java 程序中解密该数据。在 Python 中,我是这样加密的:

from Crypto.Cipher import AES
KEY = '12345678901234567890123456789012'

def encrypt(data):
    cipher = AES.new(KEY, AES.MODE_CFB)
    return cipher.encrypt(data)

在 Java 中,我是这样解密的:

import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;

public class Encryption {
    private static byte[] KEY = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7',
        '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2' };

    public static byte[] decrypt(byte[] data) throws NoSuchAlgorithmException, NoSuchPaddingException,
            InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        Cipher c = Cipher.getInstance("AES/CFB/NoPadding");
        Key key = new SecretKeySpec(KEY, "AES");
        c.init(Cipher.DECRYPT_MODE, key);
        return c.doFinal(data);
    }
}

但我得到Exception in thread "main" java.security.InvalidKeyException: Illegal key size or default parameters。显然,我做错了什么。但是什么?

【问题讨论】:

  • 您是否有合适的 jar 包来支持更高强度的加密?默认情况下,java 不允许强键。您的错误与 python 结束无关,与您尝试使用的密钥有关。 stackoverflow.com/questions/2568841/… 查看 Mohamed Mansour 的答案
  • 用一个简单的小钥匙试试这个,看看它是否仍然发生。

标签: java python encryption aes


【解决方案1】:

您遇到问题的原因是安全策略将您的密钥大小限制为 128 位,并且您尝试使用 256 位密钥(需要 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files)。

查看this 的讨论,您可能会注意到您有类似的问题。我实际上在我的机器上遇到了同样的问题。更新安全策略后,我能够运行您的代码。另外,我认为您应该进行以下更改c.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(new byte[16])); 您缺少 CFB 模式的初始化向量。如果解密后的值不正确,请检查您初始化密钥的方式。

【讨论】:

  • 我假设没有办法在小程序中使用无限强度管辖策略文件,那么,有吗?
  • 那么你可能不得不选择 BouncyCastle。这是一个非常受欢迎的替代方案。
【解决方案2】:

我会强烈建议为此使用跨语言加密 API。我是Keyczar 的忠实粉丝,它恰好有Java 和Python 库。 API 非常简单:

public String encrypt(String data)
public String decrypt(String data)

在Java 和Python 中。

【讨论】:

  • 我在 KeyCzar 中看不到任何将字符串转换为键的方法。您是否必须编写自己的类才能做到这一点?该文档似乎假设您创建本地文件,并且没有提及密钥交换。
  • 关键是 KeyCzar 为您管理密钥。为什么您认为需要将字符串转换为键?您是否尝试将现有密钥与 KeyCzar 一起使用?
  • 我放弃了在 Android 应用中使用 KeyCzar 的尝试。即使我想将字符串转换为键。
【解决方案3】:
  • “abc”和“abc”等 Python 2 字符串文字是 ASCII。
  • 像 u'abc' 和 u"abc" 这样的 Python 2 字符串文字是 unicode。
  • “abc”和“abc”等 Python 3 字符串文字是 unicode。
  • 像 b'abc' 和 b"abc" 这样的 Python 3 字符串文字是字节类型。

Java 默认使用 unicode,类似于 Python 3。

对于跨语言、可互操作的加密,您可以查看https://code.google.com/p/keyczar/。该页面上有其使用的简单示例。

【讨论】:

  • “Java 默认使用 unicode” 颇具误导性。在内部,Java 将字符串存储为 UTF-16,但 Java 假定的“默认”编码完全依赖于平台。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-08
  • 1970-01-01
  • 2013-11-10
  • 1970-01-01
  • 2013-12-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多