当我使用 Java 生成的有效负载及其签名发出 post 请求时,服务器接受该请求。
当我使用相同的有效负载并使用相同的算法生成签名但现在使用 python 时,我不断收到 Bad Padding 异常。
我比较了两个程序生成的SHA,它们似乎是相同的,所以加密有问题。
我尝试了一些事情,例如:-
i). Encoded the sha with "utf-8", just like its being done in the Java code.
The resulting string was the same as the original sha and still got the
bad padding.
我感觉我必须将 sha 转换为某种特定格式加密,然后将加密消息更改为某种特定格式。模仿这些 Java 代码行:-
byte[] encrypted = cipher.doFinal(sha.getBytes("UTF-8"));
byte[] encoded = Hex.encode(encrypted);
strEncrypted = new String(encoded);
但是到目前为止我还没有成功。请帮忙。
这是我的 Java 代码(请注意,它缺少一些部分,因此无法编译。我们只对 makeDigest 和 encrypt 方法感兴趣):-
import javax.crypto.Cipher;
String payload = "something";
public static void main(String[] args) throws Exception {
String dig = makeDigest(payload, "SHA-1");
Key k = getKey();
String signature = encrypt(dig, "RSA/ECB/PKCS1Padding", k);
System.out.print(signature);
}
public static String makeDigest(String payload, String digestAlgo) {
String strDigest = "";
try {
MessageDigest md = MessageDigest.getInstance(digestAlgo);
byte[] p_b = payload.getBytes("UTF-8");
md.update(p_b);
byte[] digest = md.digest();
byte[] encoded = Hex.encode(digest);
strDigest = new String(encoded);
}
catch (Exception ex) {
ex.printStackTrace();
}
return strDigest;
}
public static String encrypt(String sha, String encryptAlgo, Key k) {
String strEncrypted = "";
try {
Cipher cipher = Cipher.getInstance(encryptAlgo);
cipher.init(Cipher.ENCRYPT_MODE, k);
byte[] encrypted = cipher.doFinal(sha.getBytes("UTF-8"));
byte[] encoded = Hex.encode(encrypted);
strEncrypted = new String(encoded);
}
catch (Exception ex) {
ex.printStackTrace();
}
return strEncrypted;
}
我尝试使用 Crypto 模块将此代码转换为 python。
我的Python代码:-
from Crypto.Hash import SHA
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
def get_payload_sha(payload):
sha = SHA.new(payload).hexdigest()
return sha
def get_sha_signature(sha):
key = RSA.importKey(open(some_private_key, "r").read())
cipher = PKCS1_v1_5.new(key)
cipher_text = cipher.encrypt(sha)
signature = cipher_text.encode("hex")
return signature
payload = "something"
sha = get_payload_sha(payload)
signature = get_sha_signature(sha)
print signature
错误
ERROR 96 25-08-2015 10:46:08 Exception decrypting signature [signature=dfg23fghdf2349a3e87e3] : javax.crypto.BadPaddingException: unknown block type
javax.crypto.BadPaddingException: unknown block type
at org.bouncycastle.jce.provider.JCERSACipher.engineDoFinal(Unknown Source)
at javax.crypto.Cipher.doFinal(DashoA13*..)
最佳答案
您正在尝试使用私钥加密十六进制编码的哈希值。此操作称为签名,并在内部使用私有(private)指数 d
完成。
如果您只是在 pycrypto 中使用 RSA key (公共(public)或私有(private))加密某些内容,那么您始终使用公共(public)指数 e
( ref )。
您需要为此使用签名生成:
from Crypto.Signature import PKCS1_v1_5
cipher = PKCS1_v1_5.new(key)
signature = cipher.sign(sha)
但这可能不起作用,因为用于加密和签名的填充是不同的。因此,即使 Java 代码确实有效,签名也不太可能是正确的。
您可以尝试交换 e
和 d
作为快速修复:
from Crypto.Cipher import PKCS1_v1_5
temp = key.d
key.d = key.e
key.e = temp
cipher = PKCS1_v1_5.new(key)
signature = cipher.encrypt(sha)
关于java - 我应该如何正确地将Java加密算法移植到Python?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32197342/