【问题标题】:Java RSA encrypted AES keyJava RSA 加密的 AES 密钥
【发布时间】:2015-03-30 19:57:35
【问题描述】:

我有一个 RSA 私钥,我正在尝试解密其中包含 AES 密钥的另一个文件内容。到目前为止,我似乎能从这些过程中得到回报的是行话。不太确定我在下面的代码中做错了什么。我在谷歌上看过,至少有 100 种不同的方法。

import java.io.*;
import java.io.IOException;

import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.GeneralSecurityException;
import java.security.spec.PKCS8EncodedKeySpec;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;

import org.apache.commons.codec.binary.Base64;

import org.apache.commons.io.FileUtils;

public class RsaEncryption {
    private Cipher _pkCipher;

    public RsaEncryption() throws GeneralSecurityException {
        // create RSA public key cipher
        _pkCipher = Cipher.getInstance("RSA");
    }

    public String loadKey(File in, String privateKey) throws GeneralSecurityException, IOException, Exception {
        privateKey = privateKey.replaceAll("-+.*?-+", "");
        byte[] encodedKey = Base64.decodeBase64(privateKey);

        // create private key
        PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedKey);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        RSAPrivateKey pk = (RSAPrivateKey) kf.generatePrivate(privateKeySpec);

        // read AES key
        _pkCipher.init(Cipher.DECRYPT_MODE, pk);
        byte[] encryptedBytes       = FileUtils.readFileToByteArray(in);
        ByteArrayInputStream fileIn = new ByteArrayInputStream(encryptedBytes);
        CipherInputStream cis       = new CipherInputStream(fileIn, _pkCipher);
        DataInputStream dis         = new DataInputStream(cis);
        byte[] decryptedData        = new byte[32];
        dis.read(decryptedData);
        String key = new String(decryptedData);
        return key;
    }
}

更新

充气城堡 pem 转换器的新方法仍然无法正常工作

import java.io.StringReader;
import java.io.File;
import java.io.IOException;

import java.security.KeyPair;
import java.security.interfaces.RSAPrivateKey;
import java.security.GeneralSecurityException;
import java.security.interfaces.RSAPublicKey;

import javax.crypto.Cipher;

import org.apache.commons.io.FileUtils;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;

public class RsaEncryption {
    private Cipher _pkCipher;
    private RSAPrivateKey _PrivateKey;
    private RSAPublicKey  _PublicKey;

    public RsaEncryption(String privateKey) throws GeneralSecurityException, IOException {
        loadKey(privateKey);
        // create RSA public key cipher
        _pkCipher = Cipher.getInstance("RSA/None/PKCS1Padding", "BC");
    }

    private void loadKey(String privateKey) throws IOException {
        PEMParser pemParser          = new PEMParser(new StringReader(privateKey));
        PEMKeyPair pemKeyPair        = (PEMKeyPair) pemParser.readObject();
        JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
        KeyPair keyPair              = converter.getKeyPair(pemKeyPair);
        _PrivateKey                  = (RSAPrivateKey) keyPair.getPrivate();
        _PublicKey                   = (RSAPublicKey) keyPair.getPublic();
        pemParser.close();
    }

    public String decrypt(File in) throws GeneralSecurityException , IOException{
        _pkCipher.init(Cipher.DECRYPT_MODE, _PrivateKey);
        byte[] encryptedBytes = FileUtils.readFileToByteArray(in);
        String key = new String(_pkCipher.doFinal(encryptedBytes));
        System.out.println(key);
        return key;
    }


    public RSAPrivateKey getPrivateKey() { return _PrivateKey; }
    public RSAPublicKey getPublicKey()   { return _PublicKey;  }
}

【问题讨论】:

  • 什么是“行话”?如果没有任何异常,那么您将取回您的密钥。
  • 如果我尝试将密钥打印为空白,但长度为 32。然后当我将它传递给 AES 类以尝试解密某些内容时,我只会得到废话,这就是我所说的行话.
  • 请定义数据的加密方式以及密文的布局方式。用 AES 加密的实际数据密文在哪里?包含 AES 密钥的 RSA 密文在哪里?两者是如何加密的?
  • 我们有一个密钥文件和一个 IV 文件。它们都使用公共 RSA 密钥加密。 RSA 私钥存储在 yaml 文件中。将 RSA 私钥加载到字符串中。然后尝试使用私有 RSA 密钥解密密钥或 IV 文件。 AES 部分并不重要,它获取 AES 所需的密钥是 RSA 加密文件的问题。
  • 你忽略dis.read(decryptedData);中读取返回的字节数@返回多少字节?

标签: java encryption cryptography aes rsa


【解决方案1】:

RSA 只能加密少量必须作为块处理的数据。你不需要一个流。只需调用

byte[] aesKey = _pkCipher.doFinal(FileUtils.readFileToByteArray(in));

获取 AES 密钥。

【讨论】:

  • 所以这是我最初走的路线。我得到这个错误。 javax.crypto.BadPaddingException:在 sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:380) ~[na:1.8.0_11] 在 sun.security.rsa.RSAPadding.unpad(RSAPadding.java:291) 处的解密错误~[na:1.8.0_11] at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:354) ~[sunjce_provider.jar:1.8.0]
  • 我忘记将加密密钥传递给解密方法。如果这不起作用,AES 密钥是如何加密的?是真的使用了 PKCS1Padding 还是使用了 OAEP?
  • 传入字节数组时出现错误。这是我最初的打算。私钥最初是用 ruby​​ 生成的,与其他所有内容相同。私钥:OpenSSL::PKey::RSA.generate(2048).to_s.each_line.collect { |line| " #{line}" }.join('')
  • 请显示 AES 密钥是如何加密的,而不是 RSA 密钥是如何生成的 - 将其编辑到问题的底部。
  • 不,据我所知不需要。原始海报或回答者不需要@。该死,现在我不确定了。
【解决方案2】:

在错误目录中的 JCE jar 在放入正确目录后就可以正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-26
    • 2018-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多