【发布时间】:2019-02-26 17:59:35
【问题描述】:
免责声明:我的密码学很糟糕,我对 RSA 或密码验证知之甚少。
我需要在 Python 中验证已签名的许可证。我使用了“带有 SHA256 摘要的 RSA PKCS1 v1.5 填充”。背景信息是我正在尝试使用https://keygen.sh 分发软件。
基本上,二进制软件安装在服务器上,并验证存储在服务器上的许可证文件是真实的。为此,该软件可以访问我的 RSA 公钥。我有一段代码在 Node.js 中工作,来自the official keygen documentation,我试图将它移植到 Python,但没有成功。我已选择使用 cryptodome 库,但我对其他选项持开放态度。
这是 Node.js 中的工作代码:
const crypto = require('crypto')
const public_key = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtmwlw+mDo2ZVBlRXa7Em\ncj7cVrlwnwrIPC+Ij5KpltadJfwvRFvCr37USJvkc+FIND2dKk2mmbY32cvtxl3F\nYLpjRwwlFuajbP8ZEdJl1YJyJDnLlKHWEfTSvTzZhpT939yjuBKoZ9A+wiIQ9tzY\nF/ytb9zwPkOF7/XmPAaukah5xRgwsb3fo7E0CsBQuHZxFX83+nfdZ/60MWpSCWL6\nAjNWDEmoLFEHVRm69+lwXTW51wojfurZy/wUw42sciHLV5A8mz7gJJGO5y+sGzzD\nM5VxtmLz51Fl1Rl3fMzUAjPK77i9UDWo11EuNPrzMAgjmuuMLfpIDMlMR3n/ZsW7\nXwIDAQAB\n-----END PUBLIC KEY-----\n"
const key = 'somerandomkey'
const encodedSignature = "oMTrvIz3IX4kre5UTzvkzCn712wulPvl9knSYBduYcGsX2W703zWMC9ZVepDytxLdpUIiCUtx6wx5OzmLx3rTzgaKqptrbf2wYHrCIPBgrhcHdJ3fLJRh8ASC_NdLK6i1jC_bEAq84d7QNLlTPC20aCmNLdxEJFy-DValGG0iFdxx6n6-Vp5oL8jSyWubAvBSqEQ4ubptcYirxpbDdC4DRpNzBuA48DGxWg6Pxq5HdGZWKS05iohNlrFkW-K8NJYHuLKszT0FN5UWcghx1oklagCm72aDvXm3CzKL2id7yL78X_V69JYsExx3fjRsU0pUe-f5lzKLB_HLTAdc0e1gQ=="
const verifier = crypto.createVerify('sha256')
verifier.write(key)
verifier.end()
const ok = verifier.verify(public_key, encodedSignature, 'base64')
if (ok) {
console.log('License key is valid!')
} else {
console.log('License key is invalid!')
}
运行这段代码 (nodejs verify.js) 会打印出License key is valid!。
这是失败的代码,在 Python 中:
import base64
# pip install pycryptodome
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
import Crypto.Signature.pkcs1_15
import Crypto.Util.Padding
public_key = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtmwlw+mDo2ZVBlRXa7Em\ncj7cVrlwnwrIPC+Ij5KpltadJfwvRFvCr37USJvkc+FIND2dKk2mmbY32cvtxl3F\nYLpjRwwlFuajbP8ZEdJl1YJyJDnLlKHWEfTSvTzZhpT939yjuBKoZ9A+wiIQ9tzY\nF/ytb9zwPkOF7/XmPAaukah5xRgwsb3fo7E0CsBQuHZxFX83+nfdZ/60MWpSCWL6\nAjNWDEmoLFEHVRm69+lwXTW51wojfurZy/wUw42sciHLV5A8mz7gJJGO5y+sGzzD\nM5VxtmLz51Fl1Rl3fMzUAjPK77i9UDWo11EuNPrzMAgjmuuMLfpIDMlMR3n/ZsW7\nXwIDAQAB\n-----END PUBLIC KEY-----\n"
license_key = b'somerandomkey'
encoded_license_signature = """oMTrvIz3IX4kre5UTzvkzCn712wulPvl9knSYBduYcGsX2W703zWMC9ZVepDytxLdpUIiCUtx6wx5OzmLx3rTzgaKqptrbf2wYHrCIPBgrhcHdJ3fLJRh8ASC_NdLK6i1jC_bEAq84d7QNLlTPC20aCmNLdxEJFy-DValGG0iFdxx6n6-Vp5oL8jSyWubAvBSqEQ4ubptcYirxpbDdC4DRpNzBuA48DGxWg6Pxq5HdGZWKS05iohNlrFkW-K8NJYHuLKszT0FN5UWcghx1oklagCm72aDvXm3CzKL2id7yL78X_V69JYsExx3fjRsU0pUe-f5lzKLB_HLTAdc0e1gQ=="""
license_signature = base64.b64decode(encoded_license_signature)
# Padding: none of these solutions work
# license_signature = Crypto.Util.Padding.pad(license_signature, 8, style='pkcs7')
# license_signature = Crypto.Util.Padding.pad(license_signature, 8, style='iso7816')
# license_signature = Crypto.Util.Padding.pad(license_signature, 8, style='x923')
# Custom zero-padding (doesn't work either)
#license_signature = (8 - len(license_signature) % 8)*bytes([0]) + license_signature
#license_signature = license_signature + (8 - len(license_signature) % 8)*bytes([0])
rsa_public_key = RSA.import_key(public_key)
signature = Crypto.Signature.pkcs1_15.new(rsa_public_key)
license_hash = SHA256.new(data=license_key)
print(signature.verify(license_hash, license_signature))
运行这段代码 (python3 verify.py) 会引发错误:
Traceback (most recent call last):
File "verify.py", line 30, in <module>
print(signature.verify(license_hash, license_signature))
File "/home/user/venvs/tutor/lib/python3.6/site-packages/Crypto/Signature/pkcs1_15.py", line 111, in verify
raise ValueError("Invalid signature")
ValueError: Invalid signature
# Step 1
if len(signature) != k:
raise ValueError("Invalid signature")
我认为这是由不正确的填充引起的,因此我对签名填充进行了不同的尝试,您可以在我的代码中看到这些尝试,但都不起作用。但至少,它们让我超越了签名验证的第一步。我现在卡在fourth and final step:
Traceback (most recent call last):
File "verify.py", line 30, in <module>
print(signature.verify(license_hash, license_signature))
File "/home/user/venvs/tutor/lib/python3.6/site-packages/Crypto/Signature/pkcs1_15.py", line 137, in verify
raise ValueError("Invalid signature")
ValueError: Invalid signature
知道如何解决这个问题吗?如有必要,我已准备好使用不同于 cryptodome 的东西。
【问题讨论】:
标签: python encryption cryptography rsa pkcs#1