簡體   English   中英

RSA 在 python 中用私鑰對字符串進行簽名

[英]RSA sign a string with private key in python

我正在與我們的客戶服務器通信。 對於 api,我需要用我的私鑰簽署一個字符串。 他們有以下條件可以遵循

  1. 使用SHA 256算法計算字符串的hash
  2. 使用私鑰和 RSA (PKCS1_PADDING) 算法對 Hash Value 進行簽名。
  3. Base64對加密后的Hash值進行編碼

我正在做以下

from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
import base64


pkey = RSA.importKey(keystring)

message = "Hello world"

h = SHA256.new(message.encode())
signature = PKCS1_v1_5.new(pkey).sign(h)
result = base64.b64encode(signature).decode()

結果我得到了一個字符串。 但是在服務器端我的簽名不匹配。

我有什么問題嗎? 誰可以幫我這個事?

我最近回到這個問題並注意到它從未得到解決。 我不知道 OP 設置出了什么問題,但以下代碼對我有用。

首先,生成"Hello world"簽名的 python 代碼:

from Cryptodome.Signature import PKCS1_v1_5
from Cryptodome.Hash import SHA256
from Cryptodome.PublicKey import RSA
import base64


def sign(message: str, private_key_str: str) -> str:
    priv_key = RSA.importKey(private_key_str)
    h = SHA256.new(message.encode('utf-8'))
    signature = PKCS1_v1_5.new(priv_key).sign(h)
    result = base64.b64encode(signature).decode()
    return result

現在驗證它的 Java 代碼:

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

...
...

    public static boolean verify(String message, String b64Sig, byte[] pubkey_spki) throws GeneralSecurityException {
        var pubKey = (PublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(pubkey_spki));
        var verifier = Signature.getInstance("SHA256withRSA");
        verifier.initVerify(pubKey);
        verifier.update(message.getBytes(StandardCharsets.UTF_8));
        return verifier.verify(Base64.getDecoder().decode(b64Sig));
    }

也許其中最棘手的部分是在每種語言/庫中指定正確的填充方案。 這些簽名使用PKCS#1 RFC 8017中標識為RSASSA-PKCS1-v1_5的方案。 On the python side this is accomplished by providing the SHA256 hash object to the PKCS1_v1_5 signature object. In Java it is perhaps a little more straightforward in that you ask for Signature object that implements the RSA algorithm with SHA256 as the hash function, but still have知道這是 RSASSA-PKCS1-v1_5 而不是 RFC 8017 中的其他可能性。

我認為,如果一個人還不是專家,那么理解 python 和 Java 中的這些神奇選擇會產生兼容代碼將會很困難。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM