duanhongyi / gmssl

a python crypto for sm2/sm3/sm4
MIT License
479 stars 140 forks source link

您好,希望您百忙之中解答一下:SM2+SM4解密失败 #5

Closed zzltjnh closed 4 years ago

zzltjnh commented 5 years ago

ps_de_skey = 'BI01pjJKUnpeM7hhDAAbJR2t/3CGM4glBoxFsRKBXNuNQiW9ZnE2jmpYQvZ4i/ysmfDC2ZpgZz2EKmwJeN3IpwqNAQV1KTqAb9kIJsnYnjs8F0jd+UXc5LoQHxrloFlcs86MW1k7cSvH3+8+fI4NZjA=' ps_cipher_data = 'z+Dkv9xyPICbx3qe+GKBGUGQ7jxPVz8iYh/Fy+uZ/uiQYSfwnlCHcVwuMl4xjIIYpVoq9I9yvgMH9052GkCvKg==' private_key = '806eebd45a09f6ac9333d70c01358fb33dcb6eedd3ba6f9f786eca4d800d610e' sm2_crypt = CryptSM2(private_key=private_key, public_key=None) key_enc_data = base64.b64decode(ps_de_skey.encode()) print('key_enc_data:', key_enc_data) key_dec_data = sm2_crypt.decrypt(enc_data) print('key_dec_data:', key_dec_data) crypt_sm4 = CryptSM4() input = base64.b64decode(ps_cipher_data.encode()) crypt_sm4.set_key(key_dec_data, SM4_DECRYPT) decrypt_value = crypt_sm4.crypt_ecb(input) print('decrypt_value:', decrypt_value) 代码如上,逻辑为:

  1. 利用private_key对ps_de_skey进行SM2解密得到key_dec_data 2.利用key_dec_data对ps_cipher_data进行SM4解密得到decrypt_value 执行以上代码后不能得到实际正确的结果 我这里有一个java的算法能得出正确结果,代码如下 SM2Cipher sm02 = SM2Cipher.getInstance(); byte[] encryptData = Base64.decode(ps_de_skey.getBytes());

    byte[] keyData = sm02.decrypt(encryptData, Hex.decode(privateKeyHexStr.getBytes())); Key key = new SecretKeySpec(keyData, "SM4");

    String decryptValue = decrptyData(ps_cipher_data, key); System.out.println("decryptValue:" + decryptValue);

public static String decrptyData(String data, Key key) throws Exception { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

Cipher in;
@SuppressWarnings("unused")
CipherInputStream cIn;
@SuppressWarnings("unused")
ByteArrayInputStream bIn;

in = Cipher.getInstance("SM4/ECB/PKCS5Padding", "BC");

in.init(Cipher.DECRYPT_MODE, key);

byte[] input = Base64.decode(data.getBytes());

int len = in.getOutputSize(input.length);
byte[] out = new byte[len];
int len1 = in.update(input, 0, input.length, out, 0);
int len2 = in.doFinal(out, len1);

int total = len1 + len2;
if (total < len) {
  byte[] out2 = new byte[total];
  System.arraycopy(out, 0, out2, 0, total);
  return new String(out2);
}

return new String(out);

} 最终java打印出的decryptData为:{“name”: "xxx", ...} 用您的算法打印出的decryptdata为:b'\xce=g\x8bOJ\xaf\x18\xe4gN\x914\xa7\x18\xc5E\xe4\xa98u\xc5U\xc3\xc82\xcbh.\xce\xc04\xb8\xddtF\xa48\xb1%\xf1\xb4X\x93IS\xee\xd5\x12\x9b\x0e\xc7\x19\x19\xbb\x81\xbc|,\xb7\xde'

zzltjnh commented 5 years ago

补充两点: 1.我的逻辑只涉及解密,所以public_key传了None 2.怀疑是SM2算法问题,用您的代码和对ps_de_skey解密出来的结果和用java解密的结果不一致