使用Java进行非对称文件加密

时间:2017-05-29 08:13:44

标签: java encryption rsa x509certificate jce

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

end;

我称之为:

<CSSTransitionGroup 
 className="container result"
 transitionName="test"
 transitionEnterTimeout={500}
 transitionLeaveTimeout={300}>
>
  <div key="transition-group-content" >
    You prefer <strong>{props.testScore}</strong>!
  </div>
</CSSTransitionGroup>

但是我收到了这个错误:

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();
        }
    }
}

我使用了无限制JCE政策但没有改变。当我尝试使用消化的密钥时它不起作用我认为因为它切割的密钥并且不再有效

有什么建议吗?

1 个答案:

答案 0 :(得分: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)。
  5. 解密

    1. 从流中读取AES密钥,随机数和摘要
    2. 使用您的RSA私钥解密密钥
    3. 阅读并解密内容
    4. 计算解密内容的摘要并将其与已读取的哈希进行比较,如果不匹配则失败
    5. 这似乎很复杂,但跳过这些步骤中的任何一个都可能(并且经常会)导致加密被破坏。即使这些步骤也需要具有一些属性(固定的执行时间等,但是为了开始你应该没问题。)