Openssl ECDSA按原样签名输入-无摘要

Openssl ECDSA按原样签名输入-无摘要,openssl,rsa,bouncycastle,sign,ecdsa,Openssl,Rsa,Bouncycastle,Sign,Ecdsa,我正在尝试使用openssl对现有摘要进行签名 假设我已经有了一个摘要“mydigest”。尽管如此,我不想使用: echo -n "mydigest" | openssl dgst -sha256 -sign key.pem | openssl enc -A -base64 我有ECDSA而不是rsa,所以我假设我不应该使用rsautl,因为它正在按原样使用输入 因此,我的假设是,我需要一个按原样输入的东西(mydigest),并用我的ECDSA私钥对其进行签名 我尝试了以下操作,以查看使用

我正在尝试使用
openssl
对现有摘要进行签名

假设我已经有了一个摘要“mydigest”。尽管如此,我不想使用:

echo -n "mydigest" | openssl dgst -sha256 -sign key.pem | openssl enc -A -base64
我有ECDSA而不是rsa,所以我假设我不应该使用
rsautl
,因为它正在按原样使用输入

因此,我的假设是,我需要一个按原样输入的东西(mydigest),并用我的ECDSA私钥对其进行签名

我尝试了以下操作,以查看使用不同哈希算法创建的哈希大小是否对签名结果有任何影响:

echo -n "mydigest" | openssl pkeyutl -sign -inkey key.pem | openssl enc -A -base64

但就输出长度而言,这两个命令的输出大小是相同的。我假设对于大的my very..long摘要,它应该返回更大的输出(因为它应该按原样接收输入,而不缩短(哈希)

========================================

编辑。

也许下面的例子有助于理解我的问题。这是一个关于bouncycastle的例子

//签名
String messageToSign=“某物要签名”;
ECDomainParameters域=新的ECDomainParameters(spec.getCurve()、spec.getG()、spec.getN());
ECDSASigner signer=新的ECDSASigner();
init(true,新的ECPrivateKeyParameters(privateKey,domain));
MessageDigest=MessageDigest.getInstance(“Keccak-256”);
byte[]hash=digest.digest(messageToSign.getBytes(StandardCharsets.UTF_8));
BigInteger[]签名=signer.generateSignature(哈希);
让我们假设我有以下几点:

  • 散列
  • 钥匙
  • 现在我想用
    openssl
    创建签名,它应该将
    hash
    keys
    作为输入,而不创建hash

    BigInteger[] signature = signer.generateSignature(hash);
    
    在使用openssl的示例中

    openssl * ????? *
    

    我假设结果的大小应该表明我用于哈希的哈希(具有不同摘要大小)算法是否对结果有任何影响。

    openssl pkeyutl-sign-inkey ecprivkey.pem
    完全正确

    我假设对于大的my very..long摘要,它应该返回更大的输出(因为它应该按原样接收输入,而不缩短(哈希)

    您的假设是错误的。ECDSA签名在数学上由两个整数(r,s)组成,范围为1到曲线子组的顺序;它完全不受用作(或在)输入的哈希大小的影响。建议使用大小与子组匹配的哈希,例如SHA256(或您的Keccak256)对于P-256又名secp256r1——因为否则,如果散列太大,它将被截断;如果散列太小,它将被填充,或者降低安全性

    对于DSA,尤其是RSA,情况也是如此——对于RSA,签名始终是RSA密钥的大小,小于RSA密钥的经过编码和填充的哈希将被填充,但过大的哈希将被视为错误而拒绝。(这是非常罕见的,因为2048位以下的RSA密钥不再被认为是可接受的安全使用密钥,也没有人使用如此大的哈希值。)

    ECDSA签名表示(或编码)的大小可能会有所不同,并且有几种不同的标准。OpenSSL始终使用中所示的ASN.1整数序列。Java中的标准SunEC提供程序也是如此,默认情况下Java中的BouncyCastle提供程序也是如此。ASN.1编码的长度取决于,通常仅稍微取决于,关于两个整数的值,正如您正确地注意到的,这两个整数由随机值(k)控制,因此实际上是伪随机数本身。请参见(交叉)和


    Bouncy提供程序还支持{hash}和{PLAIN-,CVC-}ECDSA'算法,这些算法执行相同的数学签名,但使用P1363定义的更简单的表示形式,即两个固定大小(等于子组顺序大小)的(无符号双端)整数JWS也使用这种表示法。最后,您显示的弹性LWAPI返回或接受
    BigInteger[]
    ——数学值——编码和解码由您决定。

    很难理解您的要求。您的所有示例,包括RSA,在对其应用公钥原语之前,首先将所有输入(无论有多大)散列到固定长度的输出中。无论nput为1字节或1 PB。@PresidentJamesK.Polk感谢您的评论。我在OP中添加了一个示例。长话短说,我只想使用openssl替换BigInteger[]signature=signer.generateSignature(hash);和命令行openssl。但可能不可能:)…我还查看了帖子:。因此,如果我使用
    -pkeyopt digest:$hash
    它将不会执行rfc3447第9.2节中EMSA-PKCS1-v1_5-ENCODE的步骤1-这基本上就是哈希?我明白了,谢谢你的示例。我想我希望openssl命令以相同的格式返回签名。当然,它们不会返回相同的签名是的,因为ECDSA包含一个随机组件。这是我用openssl命令行可以得到的最接近的组件:
    echo-n“mydigest”| openssl pkeyutl-inkey ecdsa1-priv.pem-sign-asn1parse
    谢谢!啊……我没有意识到输出只有(r,s)。感谢您的精彩解释。因此,对于验证,我肯定需要1.签名,2.原始数据3.公钥。我还需要用于哈希/摘要计算的哈希函数吗?Vlado:是的,您必须使用相同的哈希进行验证,也必须使用相同的曲线,尽管有些公钥表示(包括3279中其他地方的一个)包括curve规范。但是,考虑到只有十几个常用的散列,如果需要,您可以通过反复试验找到正确的散列。
    openssl * ????? *