java - 我应该如何正确地将Java加密算法移植到Python?

标签 java python encryption character-encoding cryptography

当我使用 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 代码确实有效,签名也不太可能是正确的。

您可以尝试交换 ed 作为快速修复:

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/

相关文章:

python - 在 Pandas 中找到最接近给定时间的 DataFrame 行

python - 在另一个容器内使用Docker容器的数据

python - RSA实现解密/加密

解密信用卡号时返回 javax.crypto.IllegalBlockSizeException

.net - .NET FormsAuthentication.Encrypt() 方法使用什么加密方法?

Java:ZonedDateTime - 解析没有时区的时间字符串

java - 为什么在编译同一包的不同文件时向上移动一级

java - MySQL事务回滚异常: Deadlock found when trying to get lock;

python - 关闭 PYQT MainFrame 时如何关闭多处理

java - Switch语句——JVM内存分配、堆栈溢出