如何手动解密EncryptedAssertion [英] How to decrypt EncryptedAssertion manually
问题描述
我想解密EncryptedAssertion。我尝试使用OpenSaml Decrypter,但它不适用于我。我无法解密EncryptedData
我已经问过这个问题 -
我试过下面的代码
CipherValue cv = encryptedAssertion.getEncryptedData()。getKeyInfo()。getEncryptedKeys()。get(0).getCipherData()。getCipherValue() ;
String cvalue = cv.getValue();
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.DECRYPT_MODE,getPrivateKey());
String decryptedValue = new String(cipher.doFinal(DatatypeConverter.parseBase64Binary(cvalue)));
我不确定我是否在正确的道路上,但在上面的decryptedValue是我的解密密钥加密数据。此decryptedValue不是可读格式。不知道下一步该做什么。
getPrivateKey方法
public PrivateKey getPrivateKey(){
Key key = null;
PrivateKey privateKey = null;
try {
KeyStore ks = KeyStore.getInstance(pkcs12,SunJSSE);
ks.load(new FileInputStream(prvkey.pfx),。toCharArray());
枚举< String> aliases = ks.aliases();
while(aliases.hasMoreElements()){
String alias = aliases.nextElement();
key = ks.getKey(别名,。toCharArray());
privateKey =(PrivateKey)键;
}
} catch(例外e){
e.printStackTrace();
}
}
根据我的编码建议,如下所示。不确定我是否正确,我也收到错误
`CipherValue cv = encryptedAssertion.getEncryptedData()。getKeyInfo() 。.getEncryptedKeys()得到(0).getCipherData()getCipherValue()。
String cvalue = cv.getValue();
Cipher cipher = Cipher.getInstance(RSA / ECB / PKCS1Padding);
cipher.init(Cipher.UNWRAP_MODE,getPrivateKey());
密钥decryptionKey = cipher.unwrap(DatatypeConverter.parseBase64Binary(cvalue),RSA / ECB / PKCS1Padding,Cipher.SECRET_KEY);
CipherValue cdata = encryptedAssertion.getEncryptedData()。getCipherData()。getCipherValue();
String cdataValue = cdata.getValue();
byte [] iv =新字节[256/16];
IvParameterSpec ivParamSpec = new IvParameterSpec(iv);
Cipher cipher2 = Cipher.getInstance(AES / CBC / PKCS5PADDING);
SecretKeySpec spec = new SecretKeySpec(decryptionKey.getEncoded(),AES);
cipher2.init(Cipher.DECRYPT_MODE,spec,ivParamSpec);
字符串decryptedValue = new String(cipher2.doFinal(DatatypeConverter.parseBase64Binary(cdataValue)));`
错误 -
线程main中的异常javax.crypto.BadPaddingException:给定最终块未正确填充
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)
at com。 sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436)
at javax.crypto.Cipher.doFinal(Cipher.java:2121)
UPDATE ::
希望我根据评论正确地做到这一点。
byte [] iv = new byte [256/16];
iv = Arrays.copyOfRange(DatatypeConverter.parseBase64Binary(cdataValue),0,16);
byte [] cipherBlock = Arrays.copyOfRange(DatatypeConverter.parseBase64Binary(cdataValue),16,DatatypeConverter.parseBase64Binary(cdataValue).length);
IvParameterSpec ivParamSpec = new IvParameterSpec(iv);
Cipher cipher2 = Cipher.getInstance(AES / CBC / PKCS5PADDING);
SecretKeySpec spec = new SecretKeySpec(decryptionKey.getEncoded(),AES);
cipher2.init(Cipher.DECRYPT_MODE,spec,ivParamSpec);
String decryptedValue = new String(cipher2.doFinal(cipherBlock)); //相同的错误 - 给定的最后一个块没有正确填充
我不会给你一个完整的答案,但我希望能让你走上正确的轨道
你不应该只是用私钥解密这个calue。
首先使用RSA / ECB / PKCS1Padding解密KeyInfo值(解包aes密钥)(根据提供的saml片段)
<它应该给你一个256位(32字节)随机密钥用于加密数据本身
然后使用AES密钥解密数据。请注意,第一个字节(128位/ 16字节,aes块大小)用作IV。
进一步阅读
- https://www.w3.org/TR/2002/REC-xmlenc -core-20021210 / Overview.html#sec-Processing-Encryption
- https://gusto77.wordpress.com/2017/10/30/encryption-reference-project/
I want to decrypt the EncryptedAssertion. I tried with OpenSaml Decrypter but its not working for me.I am getting Failed to decrypt EncryptedData I have already ask that question - EncryptedAssertion Decryption failing
While I am waiting for any solution I am trying to decrypt it manually. Its a Hybrid encryption
I tried below code
CipherValue cv = encryptedAssertion.getEncryptedData().getKeyInfo().getEncryptedKeys().get(0).getCipherData().getCipherValue();
String cvalue = cv.getValue();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, getPrivateKey());
String decryptedValue = new String(cipher.doFinal(DatatypeConverter.parseBase64Binary(cvalue)));
I am not sure if I am on the right path, but above decryptedValue is the decryption key for my Encrypted Data.This decryptedValue is not in readable format. Not sure what to do next.
getPrivateKey method
public PrivateKey getPrivateKey(){
Key key = null;
PrivateKey privateKey = null;
try {
KeyStore ks = KeyStore.getInstance("pkcs12", "SunJSSE");
ks.load(new FileInputStream("prvkey.pfx"),"".toCharArray());
Enumeration<String> aliases = ks.aliases();
while(aliases.hasMoreElements()){
String alias = aliases.nextElement();
key = ks.getKey(alias, "".toCharArray());
privateKey = (PrivateKey)key;
}
} catch (Exception e) {
e.printStackTrace();
}
}
Based on the suggestion I coded like below. Not sure if I am doing it correct also I am getting errors
`CipherValue cv = encryptedAssertion.getEncryptedData().getKeyInfo().getEncryptedKeys().get(0).getCipherData().getCipherValue();
String cvalue = cv.getValue();
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.UNWRAP_MODE, getPrivateKey());
Key decryptionKey = cipher.unwrap(DatatypeConverter.parseBase64Binary(cvalue), "RSA/ECB/PKCS1Padding", Cipher.SECRET_KEY);
CipherValue cdata = encryptedAssertion.getEncryptedData().getCipherData().getCipherValue();
String cdataValue = cdata.getValue();
byte[] iv = new byte[256 / 16];
IvParameterSpec ivParamSpec = new IvParameterSpec(iv);
Cipher cipher2 = Cipher.getInstance("AES/CBC/PKCS5PADDING");
SecretKeySpec spec = new SecretKeySpec(decryptionKey.getEncoded(), "AES");
cipher2.init(Cipher.DECRYPT_MODE, spec, ivParamSpec );
String decryptedValue = new String(cipher2.doFinal(DatatypeConverter.parseBase64Binary(cdataValue)));`
Error -
Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436)
at javax.crypto.Cipher.doFinal(Cipher.java:2121)
UPDATE :: hope I am doing it correctly based on the comments.
byte[] iv = new byte[256/16];
iv = Arrays.copyOfRange(DatatypeConverter.parseBase64Binary(cdataValue), 0, 16);
byte[] cipherBlock = Arrays.copyOfRange(DatatypeConverter.parseBase64Binary(cdataValue), 16, DatatypeConverter.parseBase64Binary(cdataValue).length);
IvParameterSpec ivParamSpec = new IvParameterSpec(iv);
Cipher cipher2 = Cipher.getInstance("AES/CBC/PKCS5PADDING");
SecretKeySpec spec = new SecretKeySpec(decryptionKey.getEncoded(), "AES");
cipher2.init(Cipher.DECRYPT_MODE, spec, ivParamSpec );
String decryptedValue = new String(cipher2.doFinal(cipherBlock)); // Same error - Given final block not properly padded
I won't provide you a complete answer but I hope to get you on the right track
You should not just simply decrypt the calue with the private key.
First decrypt the KeyInfo value (unwrap the aes key) using RSA/ECB/PKCS1Padding (according to the provided saml snippet)
It should give you a 256 bit (32 bytes) random key used to encrypt data itself
then use the AES key to decrypt the data . Please note that first bytes (128 bit / 16 bytes, aes block size) is used as IV.
further reading
- https://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html#sec-Processing-Encryption
- https://gusto77.wordpress.com/2017/10/30/encryption-reference-project/
这篇关于如何手动解密EncryptedAssertion的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!