elixir 中的 rsa 签名与 python 代码输出不匹配

问题描述 投票:0回答:1

我有一个用于生成 rsa 签名的 python 代码,我正在尝试在 elixir 中编写此代码。 蟒蛇代码:

import sys
import base64
import datetime
import json
from Crypto.PublicKey import RSA
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA512

def generate_signature(key_id, private_key_content):
    private_key = RSA.import_key(base64.b64decode(private_key_content))

    timestamp = "2024-12-19T08:48:29.528457+00:00"
    message_to_sign = key_id + timestamp
    print("Message to sign:", message_to_sign)

    hash_obj = SHA512.new(message_to_sign.encode())
    signer = pkcs1_15.new(private_key)
    signature_bytes = signer.sign(hash_obj)
    signature_value = base64.b64encode(signature_bytes).decode()

    return json.dumps({
        "keyId": key_id,
        "timestamp": timestamp,
        "signature": signature_value
    }, indent=2)

def main():
    if len(sys.argv) < 3:
        print("required keyId and privateKey")
    else:
        key_id = sys.argv[1]
        private_key_content = sys.argv[2]
        print(generate_signature(key_id, private_key_content))

if __name__ == "__main__":
    main()

我的长生不老药代码:

defmodule RsaExample do
  require Logger

  defp api_key() do
    Application.get_env(:rsa_example, :api_key)
  end

  defp key_id() do
    Application.get_env(:rsa_example, :key_id)
  end

  def get_signature do
    dt = "2024-12-19T08:48:29.528457+00:00"

    message =
      :crypto.hash(:sha512, key_id() <> dt)
      |> Base.encode16()
      |> String.downcase()

    api_key = Base.decode64!(api_key())
    <<_::binary-size(26), der::binary>> = api_key

    key = :public_key.der_decode(:RSAPrivateKey, der)
    signature = :public_key.sign(message, :sha, key) |> Base.encode64()

    {:ok,
      %{
        keyId: key_id(),
        timestamp: dt,
        signature: signature
      }}
  end
end

我用这些参数进行了测试:

私钥:

MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC4CuxG1G1KiXFWpLXAGWI0ATKRP+Ixto9ElVqpFsPRB14Cu0TaRA6rEMW2C8LgafUYAJdrfzypB1tlfPpRH1fpQoFNkbYnec5/DJGMrh4fWkSZEflrOcSnY0CEHVG2fO0AMT4toVmgj6svfBSMf6S2sm2rjhQjMSqj87wOG3TNaIvQSaAz7UXa+hzaI7LQ0a41iUUDI6JLYH1EbvjZQQhwjgWlqy5LSeosBXtpPyfLaQDfUaV8eAB5mCt6uV5NlCGKMpvT+h9ZvT8gRn9P9PQeCScFyNdR32LVuU7WNkiu55XI5/ZXRgV6PNN3tOEHPLxn1Wl5cZ4kbQbciAF+eo0JAgMBAAECggEAC/BtdoTWWDUFXL0Pq1gaNkxzltehmV8B+U2FFZ4L8vX648t5Qn2SxAcxBEfMCxnkk/uJ1yfobAC1raZHaNbTMacmUz1mJzZwLm7GzG0JODh3ZcS0PQAA4Wj/aPKr994v08jeA0DJ2zAmx0xR2vF24oE9uxja9pN8dCleJD4kvCR1aVMJBlUow09PnZo6fsi9wAdIjs/BHVQT0mUl7Nx+fFqhLbWgJB3+EdB2sudiQ6r4P622zNR0BAeYuoS93LTFTER/6QYRYfQ4+aVYCacJs9hI0L+2SQmEteF+TS4P2PQxvryvmcYYGRnfQLtmQmdLU54eHkaY88+gKGoN9cxbbwKBgQDP/4qExV7lNhgpHnlv9KwXSRLk3nHvShqWKBm1ofRxGvF8bhp2s/6AG88AiGOUzMMJiS6sFasx6upznzWRUU6wpQYPP8SIftYPCv2f0dm4lIxi+o9KJHbt2zXYkoEwhgaWwo2h/InzWksVV4nRh1nm9UfUWbhGPg0f/DCjcjFgAwKBgQDihBjlN5HVhXn/PTmYRdad5Gv7wsRuJS3eSn0qSW2wHyQTav/4ulx5R21Vjbos5hEfP9wSzypy8VUgtpr9hWaWrV4noPInuo/STsUVYmdC81B3/dNWCVJQOVWogK6uD8Rh7jYPcR9fGMAiliYAygGekVNmy66r9talVLjkPmzPAwKBgQDAMWNATdPivjpS/Gq/rXi6x3Xi7zyeHH42k3U2JSFmxbuv+1kOqEEZBRkgZ+aEHzR1AkKTFi6rIGNlVQ69aUDp7oKL4qNqcLDBE6nJXLHuYaza5KU0oD8Yh/7YUH95Y86AzeLrdBvQNnW8kbeyWXwT8j9eE0038qxUCsaysJi5GwKBgQC8VYzFeHCekb4fg+5RNy/8U6Gc0BG2at86RcDP2gGDQEEkjACL85dTlxnG2nIDRr7RtqzqTqlCrHlVG76+L55ehYMVe/IbKjjOaYPgBdNJjThIrBh9Hn78CM+5rFSQkLd9nSwBptKopNGLcD/kxBCYoMgxXgS7Ih7RlCGuVGDvtQKBgQDFXhexzngPKboXvKl9rz19DSZ98IIbNTwX7Svc5rfvKGHN0XMGpc93SXA4WBY8ZlX6M/NNRk2Gd9ePf64dhn2uViMMAGwvsadiCV6Z2BqpQnDGKq2VpAbuFqtnCDPIfgPKY4fbHFPjcO3n/+wFqTL6grbIP7yM76Fv0oqt+/t2Yw==

密钥 ID:

1151022712

python代码输出:

Message to sign: 11510227122024-12-19T08:48:29.528457+00:00
b'11510227122024-12-19T08:48:29.528457+00:00'
{
  "keyId": "1151022712",
  "timestamp": "2024-12-19T08:48:29.528457+00:00",
  "signature": "gumnKBrIiRn4nlxOYe+2JASgngiFh71jpX8u/wfqH0bOw2S3B+X3sk+2pCYc9w3bmjZL2uMwAcb8dnN8UEZFKs03xo4s4RFjaqQpfwCKv1IFidNhilIiF7oyx2PkGBxVVAMtH0srO6wxmYKGFjOvCNSS5/edM7AwuXb4ZRe+6wQrmNMV/nwiKQ3Onqc5SnyaFjxINLo2/eiG4Ks0ngkmdT6PhPYhTW8Zy0EAZszo0ZK3W6z+uEMfQxw1veFa0TqcdJSQws9YZZIqBdw8mbZmY1CUZD7SwPT3UQZRw6eJezBtq/wcNO/afaW2MB9ejpkxNYr/+cFYglBTbNaZLzOK9g=="
}

圣水代码输出:

{:ok,
 %{
   timestamp: "2024-12-19T08:48:29.528457+00:00",
   signature: "lXl157EEip2OVA0UpR72oAiEjER0eDRXr5kr4fujwSZLj0/KPfkO5+1tRKY2rJVGIQ6/FAlMDtQqTijltLBvZXGqf8YWhU0zYiAzHmPZZ5WDg4Z08vwjhMDnhtsxk7MtTbv1ZzLPolCg0LOMlZqmVDaCADMl8QB9c8CHXKOogBGUP50+ML25OCvV6Ti9ni8QFfLR91fBeBYTFf0dZNqxOM/T3wX6qUAAcDnl0624Cp/UJOwDiHOivSYZJ+qsvR4ExoSYAK2RbZZOHuOIA2GrPgAOxsDjvHlBkMAa+e2lPdlAC6h7Thqla7sojeySiPWbkVf4KADBNOGisEVrnI0FaA==",
   keyId: "1151022712"
 }}

我尝试了不同的库来在 elixir 中使用 rsa,但我的 elixir 代码输出总是与 python 代码输出不匹配。我是密码学新手,也许我犯了一些错误?如何使签名匹配?

cryptography elixir rsa
1个回答
0
投票

两种代码都会生成不同的签名,因为 Elixir 代码执行的操作与 Python 代码不同:
在 Elixir 代码中,首先生成消息的 SHA-512 哈希,并对结果进行十六进制编码(使用小写字母)。然后使用 SHA-1 对该结果进行哈希处理并签名。
另一方面,在 Python 代码中,消息“仅”使用 SHA-512 进行散列和签名。

为了使 Elixir 代码与 Python 代码执行相同的操作,您应该省略第一次使用 SHA-512 进行的哈希处理。签名时,您应该使用消息直接和SHA-512作为摘要:

defmodule RsaExample do
  require Logger

  defp api_key() do
    #Application.get_env(:rsa_example, :api_key)
    "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC4CuxG1G1KiXFWpLXAGWI0ATKRP+Ixto9ElVqpFsPRB14Cu0TaRA6rEMW2C8LgafUYAJdrfzypB1tlfPpRH1fpQoFNkbYnec5/DJGMrh4fWkSZEflrOcSnY0CEHVG2fO0AMT4toVmgj6svfBSMf6S2sm2rjhQjMSqj87wOG3TNaIvQSaAz7UXa+hzaI7LQ0a41iUUDI6JLYH1EbvjZQQhwjgWlqy5LSeosBXtpPyfLaQDfUaV8eAB5mCt6uV5NlCGKMpvT+h9ZvT8gRn9P9PQeCScFyNdR32LVuU7WNkiu55XI5/ZXRgV6PNN3tOEHPLxn1Wl5cZ4kbQbciAF+eo0JAgMBAAECggEAC/BtdoTWWDUFXL0Pq1gaNkxzltehmV8B+U2FFZ4L8vX648t5Qn2SxAcxBEfMCxnkk/uJ1yfobAC1raZHaNbTMacmUz1mJzZwLm7GzG0JODh3ZcS0PQAA4Wj/aPKr994v08jeA0DJ2zAmx0xR2vF24oE9uxja9pN8dCleJD4kvCR1aVMJBlUow09PnZo6fsi9wAdIjs/BHVQT0mUl7Nx+fFqhLbWgJB3+EdB2sudiQ6r4P622zNR0BAeYuoS93LTFTER/6QYRYfQ4+aVYCacJs9hI0L+2SQmEteF+TS4P2PQxvryvmcYYGRnfQLtmQmdLU54eHkaY88+gKGoN9cxbbwKBgQDP/4qExV7lNhgpHnlv9KwXSRLk3nHvShqWKBm1ofRxGvF8bhp2s/6AG88AiGOUzMMJiS6sFasx6upznzWRUU6wpQYPP8SIftYPCv2f0dm4lIxi+o9KJHbt2zXYkoEwhgaWwo2h/InzWksVV4nRh1nm9UfUWbhGPg0f/DCjcjFgAwKBgQDihBjlN5HVhXn/PTmYRdad5Gv7wsRuJS3eSn0qSW2wHyQTav/4ulx5R21Vjbos5hEfP9wSzypy8VUgtpr9hWaWrV4noPInuo/STsUVYmdC81B3/dNWCVJQOVWogK6uD8Rh7jYPcR9fGMAiliYAygGekVNmy66r9talVLjkPmzPAwKBgQDAMWNATdPivjpS/Gq/rXi6x3Xi7zyeHH42k3U2JSFmxbuv+1kOqEEZBRkgZ+aEHzR1AkKTFi6rIGNlVQ69aUDp7oKL4qNqcLDBE6nJXLHuYaza5KU0oD8Yh/7YUH95Y86AzeLrdBvQNnW8kbeyWXwT8j9eE0038qxUCsaysJi5GwKBgQC8VYzFeHCekb4fg+5RNy/8U6Gc0BG2at86RcDP2gGDQEEkjACL85dTlxnG2nIDRr7RtqzqTqlCrHlVG76+L55ehYMVe/IbKjjOaYPgBdNJjThIrBh9Hn78CM+5rFSQkLd9nSwBptKopNGLcD/kxBCYoMgxXgS7Ih7RlCGuVGDvtQKBgQDFXhexzngPKboXvKl9rz19DSZ98IIbNTwX7Svc5rfvKGHN0XMGpc93SXA4WBY8ZlX6M/NNRk2Gd9ePf64dhn2uViMMAGwvsadiCV6Z2BqpQnDGKq2VpAbuFqtnCDPIfgPKY4fbHFPjcO3n/+wFqTL6grbIP7yM76Fv0oqt+/t2Yw=="
  end

  defp key_id() do
    #Application.get_env(:rsa_example, :key_id)
    "1151022712"
  end

  def get_signature do
    dt = "2024-12-19T08:48:29.528457+00:00"

    #message =
    #  :crypto.hash(:sha512, key_id() <> dt)
    #  |> Base.encode16()
    #  |> String.downcase()
    message = key_id() <> dt # fix1: apply the message directly

    api_key = Base.decode64!(api_key())
    <<_::binary-size(26), der::binary>> = api_key

    key = :public_key.der_decode(:RSAPrivateKey, der)
    signature = :public_key.sign(message, :sha512, key) |> Base.encode64() # fix2: apply SHA-512

    {:ok,
      %{
        keyId: key_id(),
        timestamp: dt,
        signature: signature
      }}
  end
end

IO.inspect RsaExample.get_signature() #... signature: "gumn...OK9g==",...
© www.soinside.com 2019 - 2024. All rights reserved.