当前位置: 首页 > 知识库问答 >
问题:

使用OpenSSL密钥的Java加密

贺子昂
2023-03-14

我有这样的情况,我使用OpenSSL生成了一个公钥/私钥对,供gdcmanon使用,遵循他们网站上列出的说明。具体地说,我使用以下命令为gdcmanon生成密钥

$ openssl genrsa -out CA_key.pem
$ openssl req -new -key CA_key.pem -x509 -days 365 -out CA_cert.cer

然后,我就能够按照他们的指示,加密一个文件,使用

gdcmanon -c CA_cert.cer -e original.dcm original_anonymized.dcm
gdcmanon -k CA_key.pem -d original_anonymized.dcm orginal_deanonymized.dcm
openssl pkcs8 -topk8 -inform PEM -outform DER -in CA_key.pem -out CA_key.pkcs8.pem -nocrypt
public static String decode(byte[] encryptedData) {
    Key key = readPEMKey(new File("CA_key.pkcs8.pem"));
    //Key key = readPEMKey(new File("CA_key.pem"));
    try {
        Cipher c = Cipher.getInstance("RSA");
        c.init(Cipher.DECRYPT_MODE, key);
        byte[] decValue = c.doFinal(encryptedData);
        String decryptedValue = new String(decValue);
        return decryptedValue;
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

private static Key readPEMKey(File key) {
    DataInputStream dis = null;
    BufferedReader reader = null;
    try {
        /*
        reader = new BufferedReader(new FileReader(key));
        String privKeyPEM = "";
        String line;
        while ((line = reader.readLine()) != null) {
            if (!line.equals("-----BEGIN RSA PRIVATE KEY-----") && !line.equals("-----END RSA PRIVATE KEY-----"))
            privKeyPEM += line + "\n";
        }
        byte[] encoded = new BASE64Decoder().decodeBuffer(privKeyPEM);
        */

        dis = new DataInputStream(new BufferedInputStream(new FileInputStream(key)));
        byte[] encoded = new byte[(int) key.length()];
        dis.readFully(encoded);

        // PKCS8 decode the encoded RSA private key
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        PrivateKey privKey = kf.generatePrivate(keySpec);
        return privKey;
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    finally {
        if (reader != null) {try {reader.close();} catch (Exception e) {e.printStackTrace();}}
        if (dis != null) {try {dis.close();} catch (Exception e) {e.printStackTrace();}}
    }
    return null;
}
javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes
at com.sun.crypto.provider.RSACipher.a(DashoA13*..)
at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at my.app.decode(Application.java:124)
java.security.InvalidKeyException: No installed provider supports this key: sun.security.rsa.RSAPrivateCrtKeyImpl
at javax.crypto.Cipher.a(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at my.app.Application.decode(Application.java:123)

这在c.init(cipher.decrypt_mode,key)行失败;

我已经为Java6安装了JCE(我正在使用)。我不知道我做错了什么。谁能给我指出正确的方向吗。

谢谢

BufferedReader reader = new BufferedReader(new FileReader(new File("CA_key.pem")));
PEMParser parser = new PEMParser(reader);
PEMKeyPair keyPair = (PEMKeyPair)parser.readObject();
AsymmetricKeyParameter privKeyParams = PrivateKeyFactory.createKey(keyPair.getPrivateKeyInfo());
AsymmetricKeyParameter publicKeyParams = PublicKeyFactory.createKey(keyPair.getPublicKeyInfo());
parser.close();

RSAEngine e = new RSAEngine();
e.init(false, publicKeyParams);
byte[] decValue = e.processBlock(encryptedData, 0, encryptedData.length);

共有1个答案

习胤运
2023-03-14

经过一大堆的努力,我终于有了下面的代码,它似乎可以工作。如果有人能告诉我一个没有BC的方法,那将是很棒的,但现在我只是很高兴它的工作。

public static String decode(byte[] encryptedData, String keyFile) {
    BufferedReader reader = null;
    try {
        reader = new BufferedReader(new FileReader(new File(keyFile)));
        PEMParser parser = new PEMParser(reader);
        PEMKeyPair keyPair = (PEMKeyPair)parser.readObject();
        AsymmetricKeyParameter privKeyParams = PrivateKeyFactory.createKey(keyPair.getPrivateKeyInfo());
        parser.close();

        CMSEnvelopedData data = new CMSEnvelopedData(encryptedData);
        RecipientInformationStore recipients = data.getRecipientInfos();

        Iterator it = recipients.getRecipients().iterator();

        if (it.hasNext()) {
            RecipientInformation recipient = (RecipientInformation)it.next();
            byte[] recData = recipient.getContent(new BcRSAKeyTransEnvelopedRecipient(privKeyParams));
            String decryptedValue = new String(recData);
            return decryptedValue;
        }
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    finally {
        if (reader != null) {try {reader.close();} catch (Exception e) {e.printStackTrace();}}
    }
    return null;
}
 类似资料:
  • 问题内容: 我正在写一种加密会话密钥的方法。它需要这样做,以便可以通过已成功测试的其他程序解密密钥。解密程序无法更改。我受困的是使我的加密工作与解密例程保持一致。 首先让我给出解密例程。请记住,这不能改变: 这是我正在编写的加密例程。我生成base64编码的文本,但最终无法解密。值得注意的是,我已验证解密例程正确获取了加密例程的结果(两者之间没有握手问题)。 我真的被卡住了。任何帮助表示赞赏。谢谢

  • 我想使用带有RSA算法的OpenSSL使用私钥加密文件: 现在,如果我执行解密操作: 此操作需要私钥 我知道我应该使用公钥进行加密,如果我使用私钥,我会得到一个签名。 然而,我想这样做是为了学习。

  • 我知道这很难...但我使用OpenSSL以一种非常标准的方式加密文件。该文件使用RSA-2048公钥在AES-256中加密。我想在Java中使用私钥解密文件。我研究了很长时间,尝试了很多方法,但似乎都行不通。我只是找到相关的问题与工作的解决方案,但不是确切地为我的问题。 我使用以下命令生成public-/private-key-pair:

  • 问题内容: 我必须使用openssl命令行或C api加密xml文件。输出应为Base64。 一个Java程序将用于解密。该程序由客户提供,不能更改(他们正在将这些代码用于旧版应用程序)。正如您在下面的代码中看到的那样,客户提供了一个密码短语,因此将使用SecretKeySpec方法生成密钥。 Java代码: 我已经测试了几个命令,例如: 但是,使用Java无法成功解密给定的输出。为了进行测试,我

  • 我正在尝试将aes-128-cbc加密与openssl一起使用,我希望密钥需要32位。但是,我注意到当我输入密钥长度为18时,openssl不会给我错误。 但是,如果我在密钥后添加0,直到它是32位,我仍然会得到相同的结果。 有文档说OpenSSL给键添加了填充吗? 编辑:我需要在代码中重现此行为。我得到了密钥,但不能保证密钥是多少位数。

  • 问题内容: 我有一个加密的私钥,并且知道密码。 我需要使用Java库对其进行解密。 不过,我宁愿不要使用BouncyCastle,除非没有其他选择。根据以前的经验,有太多更改,没有足够的文档。 私钥的格式如下: 我相信关键数据是Base64编码的,因为我看到的是64个字符。 我尝试了以下解密密钥: 我得到这个例外 我是否将正确的参数传递给构造函数? 我该如何工作? 我尝试了Ericsonn的建议,