java - 在 Python 和 Java/Scala 之间插入 RSA 签名时出现问题

标签 java python scala rsa digital-signature

我正在用 Python2 使用 python-crypto API 编写一个客户端来对 XML 文件进行数字签名,并且我有一个用 Scala 编写的服务,它可以验证签名。我的 Python 代码看起来像这样:

from Crypto.PublicKey import RSA
from Crypto.Hash import SHA
from os import urandom
import logging

...
...

生成 key ( key 大小为 2048):

self.__key = RSA.generate(self.keySize,urandom)
self.__private_key = self.__key.exportKey()
self.__public_key = self.__key.publickey().exportKey()
with open(pubPath,'w') as fpub:
    logging.info("Writing Public Key to %s" % pubPath)
    fpub.write(self.__public_key)
with open(priPath,'w') as fpri:
    logging.info("Writing Private Key to %s" % priPath)
    fpri.write(self.__private_key)

对于读入键:

self.__private_key = fpri.read()
self.__public_key = fpub.read()
self.__key = RSA.importKey(self.__private_key)

并进行数字签名

logging.debug('Data to sign: "%s"' % data)
digest = SHA.new(data.strip()).digest()
return str(self.__key.sign(digest, None)[0])

然后在 Scala/Java 中,我使用以下内容:

package com.example.security
import com.example.action.ActionRequest
import java.io.BufferedInputStream
import java.security.spec.X509EncodedKeySpec
import java.security.KeyFactory
import java.security.PublicKey
import java.security.Signature
import org.apache.log4j.Logger

class SignatureSecurityManageer extends SecurityManagerTrait {

    def loadPublicKey() : PublicKey = {
        val stream : BufferedInputStream = new BufferedInputStream(this.getClass().getResourceAsStream("/com/example/security/key.der"))
        var key = new Array[Byte](stream.available())
        stream.read(key)
        KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(key))
    }

    def securityFilter(req : ActionRequest) : Boolean = {

        var parts = req.data.split("\n\n")

        var log : Logger = Logger.getLogger(this.getClass());
        log.trace("Data \"%s\"".format(parts(0)))
        log.trace("Sig \"%s\"".format(parts(1)))

         var sg = Signature.getInstance("SHA1withRSA");
         sg.initVerify(loadPublicKey())
         sg.update(parts(0).trim().getBytes())
         sg.verify(parts(1).trim().getBytes())
    }
}

我将客户端生成的 PEM 公钥转换为二进制公钥,以便 Java 可以读取它:

openssl rsa -in src/com/example/security/key.pub -inform PEM -out src/com/example/security/key.der -outform DER -pubin

在传输中,我用双新行分隔 XML 和签名。我意识到尾随空格会带来问题,所以我在上面添加了那些 strip /修剪,我检查了日志并验证数据是否相同:

Python 客户端:

2012-04-09 14:24:51,089: Data to sign: "<?xml version="1.0" ?><AgraData><package id="Local-Laptop" timestamp="1333945491074"><sensors><sensor id="SUMTEMP001" type="Temperature" units="C"><data>8</data></sensor><sensor id="SUMVOL001" type="Volume" units="l"><data>27</data></sensor><sensor id="SUMFLO001" type="FlowRate" units="l"><data>41.142</data></sensor></sensors></package></AgraData>"

Scala 服务:

[2012-04-09 14:24:51,771] com.urbanalta.agrastore.security.SignatureSecurityManageer TRACE - Data "<?xml version="1.0" ?><AgraData><package id="Local-Laptop" timestamp="1333945491074"><sensors><sensor id="SUMTEMP001" type="Temperature" units="C"><data>8</data></sensor><sensor id="SUMVOL001" type="Volume" units="l"><data>27</data></sensor><sensor id="SUMFLO001" type="FlowRate" units="l"><data>41.142</data></sensor></sensors></package></AgraData>"

但是在 Scala 服务中,当我尝试验证签名时它返回 false。我想我在某处没有指定正确的签名/ key 类型,但我不确定在哪里。

最佳答案

这可能是 this submission 的另一个实例签名的不仅仅是摘要,还有 AlgorithmIdentifier 和摘要。

关于java - 在 Python 和 Java/Scala 之间插入 RSA 签名时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10069864/

相关文章:

java - Visual Studio Code - Java - 导入错误等

python - Django,重定向到另一个带有数据的 View

python - Flask 不渲染模板,可能是文件结构的问题

python - Pandas HDFStore : Saving and Retrieving a Series with Hierarchical Period Index

scala - 如何从传递给 scalatags 的事件处理程序访问 'this' 元素?

java - 使用 Java 确定 Derby 数据库架构版本?

java - 如何在 Spring Data JPA 中获取最后一页作为默认值

java - 修改 hibernate 文件以满足我的需要

Try[Int] 的 Scala 类型错误

scala - 从 Array 中随机选择 n 个元素