【问题标题】:Python signxml - Sign an XML document with just public/private keysPython signxml - 仅使用公钥/私钥签署 XML 文档
【发布时间】:2016-05-26 21:40:58
【问题描述】:

我正在开发一个 asp.net 应用程序的 django 端口,该应用程序仅使用公钥/私钥对生成和签署 xml 文档。

我已经成功地复制了 xml 生成的每个方面,除了签名方面。我发现 signxml 库似乎可以让我这样做,但我不知道如何让它工作。这是我得到的代码(仿照示例here):

# store keys as strings
cert = open(signprivatepath).read()
key = open(signpublicpath).read()

data = ET.fromstring(docstring)
xmldsig_stuff = xmldsig(data, 'sha1')
signed_root = xmldsig_stuff.sign(
    key=key,
    cert=cert,
    algorithm='rsa-sha1',
    c14n_algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315'
    )
verified_data = xmldsig(signed_root).verify()
return verified_data

signprivatepath 和 signpublicpath 都是 PEM 格式密钥的路径。

当我运行代码时,它返回以下错误:

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/site/245/download-site-license

Django Version: 1.9.5
Python Version: 3.5.1
Installed Applications:
['licenses.apps.LicensesConfig',
 'simple_history',
 'django.contrib.admindocs',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles']
Installed Middleware:
['simple_history.middleware.HistoryRequestMiddleware',
 'django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "C:\Users\servant\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\base.py" in get_response
  149.                     response = self.process_exception_by_middleware(e, request)

File "C:\Users\servant\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\base.py" in get_response
  147.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\projects\django\swlicensing\licenses\views\site.py" in downloadSiteLicense
  206.         signedXMLTree = signXML(treestring)

File "C:\projects\django\swlicensing\licenses\views\site.py" in signXML
  144.         c14n_algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315'

File "C:\Users\servant\AppData\Local\Programs\Python\Python35-32\lib\site-packages\signxml-1.0.0-py3.5.egg\signxml\__init__.py" in sign
  414.                 key = load_pem_private_key(self.key, password=passphrase, backend=default_backend())

File "C:\Users\servant\AppData\Local\Programs\Python\Python35-32\lib\site-packages\cryptography\hazmat\primitives\serialization.py" in load_pem_private_key
  20.     return backend.load_pem_private_key(data, password)

File "C:\Users\servant\AppData\Local\Programs\Python\Python35-32\lib\site-packages\cryptography\hazmat\backends\multibackend.py" in load_pem_private_key
  282.             return b.load_pem_private_key(data, password)

File "C:\Users\servant\AppData\Local\Programs\Python\Python35-32\lib\site-packages\cryptography\hazmat\backends\openssl\backend.py" in load_pem_private_key
  1606.             password,

File "C:\Users\servant\AppData\Local\Programs\Python\Python35-32\lib\site-packages\cryptography\hazmat\backends\openssl\backend.py" in _load_key
  1784.         mem_bio = self._bytes_to_bio(data)

File "C:\Users\servant\AppData\Local\Programs\Python\Python35-32\lib\site-packages\cryptography\hazmat\backends\openssl\backend.py" in _bytes_to_bio
  1058.         data_char_p = self._ffi.new("char[]", data)

Exception Type: TypeError at /site/245/download-site-license
Exception Value: initializer for ctype 'char[]' must be a bytes or list or tuple, not str

有没有办法做到这一点?我从中复制的代码似乎没有使用证书,只是使用了私钥本身。还是我错过了什么?

【问题讨论】:

    标签: python xml django public-key-encryption


    【解决方案1】:

    certkey 变量需要是字节数组,所以通过以下方式将其读取为字节数组

    cert = open(signprivatepath, "rb").read()
    key = open(signpublicpath, "rb").read()
    

    然后你将它传递给 sign 函数,就像你已经做的那样

    signed_root = xmldsig_stuff.sign(
        key=key,
        cert=cert,
        algorithm='rsa-sha1',
        c14n_algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315'
        )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-03
      • 2010-10-05
      • 2020-03-06
      • 2022-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多