如何手动解密EncryptedAssertion [英] How to decrypt EncryptedAssertion manually

查看:155
本文介绍了如何手动解密EncryptedAssertion的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想解密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。



进一步阅读




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

这篇关于如何手动解密EncryptedAssertion的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆