ecdsa java_java – ECDSA使用BouncyCastle签名并使用Crypto...

本文探讨了在Java和OpenSSL之间进行ECDSA签名验证时遇到的问题,原因是签名格式不同。OpenSSL和Java使用ASN.1/DER编码,而Crypto使用IEEE P1363格式。解决方案是通过Crypto库提供的DSAConvertSignatureFormat函数进行格式转换。文中给出了Crypto++代码示例,演示如何将ASN.1/DER签名转换为P1363格式,以便于跨平台验证。
摘要由CSDN通过智能技术生成

… why when I use the java code, the signature is not verified?

OpenSSL和Java使用ASN.1 / DER编码进行签名,Crypto使用IEEE P1363的签名格式.

> ASN.1:SEQUENCE :: = {r INTEGER,s INTEGER}

> P1363:[字节数组r] [字节数组s]

您需要在格式之间进行转换. Crypto提供DSAConvertSignatureFormat以在格式之间进行转换.在Elliptic Curve Digital Signature Algorithm | OpenSSL and Java Interop,加密维基上有一个例子.

这是来自wiki的加密代码.它使用OpenSSL及其命令行工具而不是Java.由于OpenSSL和Java输出ASN.1 / DER格式的签名,因此没有任何实质性差异.

#include "cryptlib.h"

#include "eccrypto.h"

#include "files.h"

#include "dsa.h"

#include "sha.h"

#include "hex.h"

#include

using namespace CryptoPP;

int main(int argc, char* argv[])

{

// Load DER encoded public key

FileSource pubKey("secp256k1-pub.der", true /*binary*/);

ECDSA::Verifier verifier(pubKey);

// Java or OpenSSL created signature. It is ANS.1

// SEQUENCE ::= { r INTEGER, s INTEGER }.

const byte derSignature[] = {

0x30, 0x44, 0x02, 0x20, 0x08, 0x66, 0xc8, 0xf1,

0x6f, 0x15, 0x00, 0x40, 0x8a, 0xe2, 0x1b, 0x40,

0x56, 0x28, 0x9c, 0x17, 0x8b, 0xca, 0x64, 0x99,

0x37, 0xdc, 0x35, 0xad, 0xad, 0x60, 0x18, 0x4d,

0x63, 0xcf, 0x4a, 0x06, 0x02, 0x20, 0x78, 0x4c,

0xb7, 0x0b, 0xa3, 0xff, 0x4f, 0xce, 0xd3, 0x01,

0x27, 0x5c, 0x6c, 0xed, 0x06, 0xf0, 0xd7, 0x63,

0x6d, 0xc6, 0xbe, 0x06, 0x59, 0xe8, 0xc3, 0xa5,

0xce, 0x8a, 0xf1, 0xde, 0x01, 0xd5

};

// P1363 'r || s' concatenation. The size is 32+32 due to field

// size for r and s in secp-256. It is not 20+20 due to SHA-1.

byte signature[0x40];

DSAConvertSignatureFormat(signature, sizeof(signature), DSA_P1363,

derSignature, sizeof(derSignature), DSA_DER);

// Cross check

std::cout << "Signature:\n";

ArraySource(signature, sizeof(signature), true, new HexEncoder(new FileSink(std::cout)));

std::cout << std::endl;

// Message "Attack at dawn!"

const byte message[] = {

0x41, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x20, 0x61,

0x74, 0x20, 0x64, 0x61, 0x77, 0x6e, 0x21, 0x0a

};

// Standard signature checking in Crypto++

// https://www.cryptopp.com/wiki/Elliptic_Curve_Digital_Signature_Algorithm

bool result = verifier.VerifyMessage(message, sizeof(message), signature, sizeof(signature));

if (result)

std::cout << "Verified message" << std::endl;

else

std::cout << "Failed to verify message" << std::endl;

return 0;

}

这是运行测试程序的结果.

$./test.exe

Signature (64):

0866C8F16F1500408AE21B4056289C178BCA649937DC35ADAD60184D63CF4A06784CB70BA3FF4FCE

D301275C6CED06F0D7636DC6BE0659E8C3A5CE8AF1DE01D5

Verified message

这是我用来重现cat test.txt |的设置openssl dgst -ecdsa-with-SHA1 -sign sample.key -keyform DER> test.sig.这是来自@ DivB在ECDSA sign with OpenSSL, verify with Crypto++的问题.

$cat test.txt

Attack at dawn!

$hexdump -C test.txt

00000000 41 74 74 61 63 6b 20 61 74 20 64 61 77 6e 21 0a |Attack at dawn!.|

00000010

# Create private key in PEM format

$openssl ecparam -name secp256k1 -genkey -noout -out secp256k1-key.pem

$cat secp256k1-key.pem

-----BEGIN EC PRIVATE KEY-----

MHQCAQEEIO0D5Rjmes/91Nb3dHY9dxmbM7gVfxmB2+OVuLmWMbGXoAcGBSuBBAAK

oUQDQgAEgVNEuirUNCEVdf7nLSBUgU1GXLrtIBeglIbK54s91HlWKOKjk4CkJ3/B

wGAfcYKa+DgJ2IUQSD15K1T/ghM9eQ==

-----END EC PRIVATE KEY-----

# Convert private key to ASN.1/DER format

$openssl ec -in secp256k1-key.pem -inform PEM -out secp256k1-key.der -outform DER

$dumpasn1 secp256k1-key.der

0 116: SEQUENCE {

2 1: INTEGER 1

5 32: OCTET STRING

: ED 03 E5 18 E6 7A CF FD D4 D6 F7 74 76 3D 77 19

: 9B 33 B8 15 7F 19 81 DB E3 95 B8 B9 96 31 B1 97

39 7: [0] {

41 5: OBJECT IDENTIFIER secp256k1 (1 3 132 0 10)

: }

48 68: [1] {

50 66: BIT STRING

: 04 81 53 44 BA 2A D4 34 21 15 75 FE E7 2D 20 54

: 81 4D 46 5C BA ED 20 17 A0 94 86 CA E7 8B 3D D4

: 79 56 28 E2 A3 93 80 A4 27 7F C1 C0 60 1F 71 82

: 9A F8 38 09 D8 85 10 48 3D 79 2B 54 FF 82 13 3D

: 79

: }

: }

# Create public key from private key

$openssl ec -in secp256k1-key.der -inform DER -pubout -out secp256k1-pub.der -outform DER

$dumpasn1 secp256k1-pub.der

0 86: SEQUENCE {

2 16: SEQUENCE {

4 7: OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1)

13 5: OBJECT IDENTIFIER secp256k1 (1 3 132 0 10)

: }

20 66: BIT STRING

: 04 81 53 44 BA 2A D4 34 21 15 75 FE E7 2D 20 54

: 81 4D 46 5C BA ED 20 17 A0 94 86 CA E7 8B 3D D4

: 79 56 28 E2 A3 93 80 A4 27 7F C1 C0 60 1F 71 82

: 9A F8 38 09 D8 85 10 48 3D 79 2B 54 FF 82 13 3D

: 79

: }

# Sign the message using the private key

$cat test.txt | openssl dgst -ecdsa-with-SHA1 -sign secp256k1-key.der -keyform DER > test.sig

# Dump the signature as hex

$hexdump -C test.sig

00000000 30 44 02 20 08 66 c8 f1 6f 15 00 40 8a e2 1b 40 |0D. .f..o..@...@|

00000010 56 28 9c 17 8b ca 64 99 37 dc 35 ad ad 60 18 4d |V(....d.7.5..`.M|

00000020 63 cf 4a 06 02 20 78 4c b7 0b a3 ff 4f ce d3 01 |c.J.. xL....O...|

00000030 27 5c 6c ed 06 f0 d7 63 6d c6 be 06 59 e8 c3 a5 |'\l....cm...Y...|

00000040 ce 8a f1 de 01 d5 |......|

00000046

# Dump the signature as ASN.1/DER

$dumpasn1 test.sig

0 68: SEQUENCE {

2 32: INTEGER

: 08 66 C8 F1 6F 15 00 40 8A E2 1B 40 56 28 9C 17

: 8B CA 64 99 37 DC 35 AD AD 60 18 4D 63 CF 4A 06

36 32: INTEGER

: 78 4C B7 0B A3 FF 4F CE D3 01 27 5C 6C ED 06 F0

: D7 63 6D C6 BE 06 59 E8 C3 A5 CE 8A F1 DE 01 D5

: }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值