【问题标题】:Asymmetric File encryption with Java使用 Java 进行非对称文件加密
【发布时间】:2017-05-29 08:13:44
【问题描述】:

我有一个包含公钥和私钥的 pfx 文件,我想使用这些密钥在我的机器上本地加密和解密文件。 那是我的代码:

public static void encryptFile(File file, PublicKey key,
        String transformation) throws NoSuchAlgorithmException,
        NoSuchPaddingException, InvalidKeyException, IOException,
        InvalidAlgorithmParameterException, NoSuchProviderException {
    Cipher c = Cipher.getInstance(transformation, "SunJCE");
    byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    IvParameterSpec ivspec = new IvParameterSpec(iv);

    SecretKeySpec secretKeySpec = new SecretKeySpec(keyb, "AES");

    c.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivspec);

    FileInputStream is = new FileInputStream(file);
    CipherOutputStream os = new CipherOutputStream(new FileOutputStream(
            new File(file.getName() + "_enc")), c);

    copy(is, os);
}

public static void decryptFile(File encryptedFile, File decryptedFile,
        Key privateKey, String transformation) {
    try {
        Cipher c = Cipher.getInstance(transformation, "SunJCE");

        byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        IvParameterSpec ivspec = new IvParameterSpec(iv);
        byte[] keyb = privateKey.getEncoded();

        SecretKeySpec secretKeySpec = new SecretKeySpec(keyb, "AES");

        c.init(Cipher.DECRYPT_MODE, secretKeySpec, ivspec);
        CipherInputStream is = new CipherInputStream(new FileInputStream(
                encryptedFile), c);
        FileOutputStream os = new FileOutputStream(decryptedFile);

        copy(is, os);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static void copy(InputStream is, OutputStream os) {

    try {
        byte[] buf = new byte[1024];
        long total = 0;
        while (true) {
            int r = is.read(buf);
            if (r == -1) {
                break;
            }
            os.write(buf, 0, r);
            total += r;
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            is.close();
            os.flush();
            os.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

我这样称呼它:

            CertificateHandler.encryptFile(new File("test.pdf"), pb, "AES/CBC/PKCS5Padding");
        CertificateHandler.decryptFile(new File("test.pdf_enc"), new File("test.enc.pdf"), pk, "AES/CBC/NoPadding");

但我收到此错误:

java.security.InvalidKeyException: Invalid AES key length: 294 bytes

我使用了 Unlimited JCE Policy,但没有任何改变。当我尝试使用摘要密钥时,我认为它不起作用,因为它切断了密钥并且不再有效

有什么建议吗?

【问题讨论】:

  • 您使用的“转换”参数是什么?尽管您在写答案时似乎遗漏了一些重要概念..
  • @gusto2 我使用“AES/CBC/PKCS5Padding”

标签: java encryption rsa x509certificate jce


【解决方案1】:

要正确加密,您会遗漏一些细节。

AES 是一种对称密码,采用密钥大小为 128、192 或 256 位。您不能只将 RSA 私钥与任何加密方案一起使用。

要使用 RSA 密钥,只需搜索网络,例如 http://www.java2s.com/Code/Android/Security/RSAencryptdecryptfunctionRSAECBPKCS1Padding.htm

通常如何加密较长的内容(文件):

(请注意有多种选项或模式,我在这里写的是一个简单的建议)

加密:

  1. 生成随机 AES 密钥(128 位即可)和随机数 (IV) - 对于 IV,请勿使用代码中的固定向量
  2. 使用 RSA 加密生成的密钥(例如 RSA/ECB/PKCS1Padding)
  3. 计算内容的摘要(散列) (sha-256)
  4. 将加密的 AES 密钥、IV、摘要和加密内容 (AES/CBC/PKCS5Padding) 写入输出流。

解密

  1. 从流中读取 AES 密钥、随机数和摘要
  2. 用你的 RSA 私钥解密密钥
  3. 阅读并解密内容
  4. 计算解密内容的摘要并将其与已读取的哈希值进行比较,如果不匹配则失败

这看起来很复杂,但跳过任何这些步骤都可能(而且经常会)导致加密被破坏。即使这些步骤也需要有一些属性(固定的执行时间等,但一开始你应该没问题)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-21
    • 2018-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    相关资源
    最近更新 更多