我有这样一种情况,即我使用OpenSSL生成了一个公钥/私钥对,以便按照其网站上列出的说明与gdcmanon一起使用。具体来说,我用下面的命令来生成我的钥匙了gdcmanon使用OpenSSL密钥进行Java加密
$ 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
加密文件及decrpyt使用
gdcmanon -k CA_key.pem -d original_anonymized.dcm orginal_deanonymized.dcm
文件
然后我想使用该键来解码Java中相应DICOM文件中的一些信息。甚至拿到钥匙在Java中挣扎之后,我发现this页,并能作出这样不会引起我的Java程序通过以下调用
openssl pkcs8 -topk8 -inform PEM -outform DER -in CA_key.pem -out CA_key.pkcs8.pem -nocrypt
了这一切之后崩溃的一个关键,很多读书,我公司生产的我已经尝试了多种方法来读取,并与私钥处理以各种方式进行解码(你可以从注释掉的部分告诉)下面的Java代码
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;
}
,但是,我还没有找到解密,将加密数据解密。如果我使用一个密码与RSA算法得到以下堆栈跟踪
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)
这失败在该行字节[] decValue = c.doFinal(的EncryptedData);
,如果我使用的密码使用AES算法得到以下堆栈跟踪
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)
这(Cipher.DECRYPT_MODE,键)未能在该行c.init;
我已经安装了JCE for Java 6(我正在使用)。我不知道我做错了什么。有人可以请我指出正确的方向。
感谢
UPDATE
我一直对这个有很多,并尝试充气城堡,以及没有结果呢。这是我第一次尝试使用Bouncy Castle的尝试。
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);
我再次获得与processBlock方法 org.bouncycastle.crypto.DataLengthException一个例外:输入太大的RSA密码。 我认为这是我以前的问题。在这里我真的很茫然,因为gdcmanon工具可以用CA_key.pem文件清楚地解密这个字符串,因为这是唯一的输入(除了要解密的文件之外)。我一直在gdcmanon源代码中寻找很多东西,它看起来好像使用了AES 256密钥,但我不明白我是如何从我生成的RSA密钥中获得的。有人可以请指点我正确的方向吗?
编辑
我已经经历了gdcmanon源就更多了,它看起来像他们使用加密消息语法(CMS)。这对我来说是全新的,但看起来BC有一大堆与CMS相关的类。具体来说,gdcmanon使用名为PKCS7_dataDecode的OpenSSL方法来解密数据。我还没有找到关于如何在Java中执行此操作的好例子。有任何想法吗?
感谢
2048位RSA私钥无法解密超过256个字节的数据,所以您的'encryptedData'参数太大。你当然不应该为你的密码使用AES算法,所以你可以忽略你的其他错误。我会专注于理解为什么你的解密输入大于预期。 –
根据gdcmanon教程我以为我做了一个AES密钥,但老实说我不确定。我对这个级别的密码很陌生,所以我不确定我做错了什么。我知道gdcmanon可以使用CA_key.pem文件正确解密这条消息,因为这是我认为我需要的唯一信息。 – Jon