我使用Bouncy Castle/Java生成签名,因为它给出了两个带有R,S值的大整数。现在的要求是使用OpenSSL命令来验证。
public static String[] generateSignature(String message) {
final ECDSASigner ecdsaSigner = new ECDSASigner();
try {
// Get private key
BCECPrivateKey ecPrivateKey = (BCECPrivateKey) JKSUtil.getPrivateKey();
if(ecPrivateKey != null) {
// Get parameter spec from private key
ECParameterSpec ecSpec = ecPrivateKey.getParameters();
// Create ECDomain object
ECDomainParameters params = new ECDomainParameters(ecSpec.getCurve(), ecSpec.getG(), // G
ecSpec.getN()); // n
// Create private key parameters
ECPrivateKeyParameters priKey = new ECPrivateKeyParameters(ecPrivateKey.getD(), // d
params);
ecdsaSigner.init(true, priKey);
// Create digest message (hash) for the actual message.
SHA256Digest keyDigest = new SHA256Digest();
keyDigest.update(message.getBytes(), 0, message.getBytes().length);
byte[] digestMessage = new byte[keyDigest.getDigestSize()];
keyDigest.doFinal(digestMessage, 0);
BigInteger[] sig = ecdsaSigner.generateSignature(digestMessage);
// Convert signature to base64
String[] base64Sig = new String[2];
base64Sig[0] = new String(Base64.encodeBase64(sig[0].toByteArray()));
base64Sig[1] = new String(Base64.encodeBase64(sig[1].toByteArray()));
String signature = base64Sig[0]+"|"+base64Sig[1];
System.out.println(signature);
return base64Sig;
}
} catch (Exception e) {
}
return null;
}
例如:我要签名的消息是“name is rs”
,运行上面的实用程序将返回R和S值,分隔符为'',在base64中编码为
ALk8VQP5XLmCIe0Kh3IE74fS55huvzv0jw==|Hj+UsStEbDYOqX98EszSET2ULE3D9kCV
现在在openssl端:
openssl enc -base64 -d -in signature.txt -out signatureToVerify.bin -A
openssl dgst -sha256 -verify eckey.pub -signature signatureToVerify.bin message.txt
它无法验证,我被困住了--在openssl端不断得到“验证失败”的错误。
OpenSSL需要X9.62签名。这包括两个整数值R和s的DER编码。如果查看provider类Signaturespi
的Bouncy Castle源代码,您会发现:
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(new ASN1Integer(r));
v.add(new ASN1Integer(s));
byte[] derEncodedSignature = new DERSequence(v).getEncoded(ASN1Encoding.DER);
这是您应该使用弹跳城堡来编码签名的。这里R
和S
应该是您在两个元素结果数组中获得的BigInteger
值。
正如您可能已经猜到的,您也可以使用Java JCAsignatural
类,这将产生相同的签名编码。如果需要或需要,您可以通过注册/指示提供者来使用BouncyCastle实现作为底层提供者。有趣的是,Bouncy Castle库现在有了一个相当快的EC实现,它胜过了Oracle提供的实现,即使是在本机代码中。
二进制输出与OpenSSL的签名输入直接兼容。要创建文本字符串,可以将字节数组编码为基本的64字符串(最好没有行尾,例如base64.encode(DerencodedSignatura)
),然后必须通过openSSL enc-base64-a-d-in signature.txt-out signaturetoverify.bin
对其进行解码
我正在写一段代码来检查签名 如果r和s是正的,我下面的代码可以工作,否则验证失败。 我的代码是 我的签名是从原始的r和s开始,以der格式创建的。请记住,如果r或s是负数,要在der格式中添加“00 ”,我还使用了BouncyCastle ANS1类 但是我仍然能够验证r和s是否为正,如果其中一个为负,我就不能验证(初始字节大于0x80) 我错过了什么? -----编辑----- 我已经创建了一个
我尝试使用java客户端对内容进行签名,然后在服务器(nodejs)上进行验证。我的客户端签名函数使用ECDSA并返回一个< code>byte[]。我可以访问服务器上包含< code>publicKey的< code>x和< code>y坐标值。 是否可以找到构成签名的和?如何将从上面获得的<code>字节〔〕对或<code>DER编码的签名 编辑: 谢谢戴夫的评论,我正在使用这个SO答案中指示
我想创建一个签名并使用openssl验证它。我想有我的签名的十六进制输出。 这是我的密码 我得到这个错误: 如果我在创建签名的过程中删除了-hex,它就可以工作了。
我正在尝试使用公钥验证散列的ECDSA签名。我写了一个小的围棋程序,成功地做到了这一点,但是我不能把它移植到C语言中。 这是我的输入数据: < li >公钥:< code > mfkwewyhkozizj 0 caqyikozij0 dackcdqgaedd 9 vxm phjv 4 vofo 0 zofplr r5 iczxquxsr 9 eka ouo 9 b 7 wl 1 daggi 0 e
我传入以下内容(摘要/哈希是SHA1): 到此功能: 但我无法在OpenSSL中验证签名(verify_success为0),即使完全相同的数据在C#中验证成功。 关于我为什么或做错了什么的任何想法? C#中的公钥是: 我假设4543533120000000是。NET特定的东西,所以我只是把04前置到它的其余部分。 这是用于验证签名的C#代码,它成功地做到了(dataBytes的SHA1在两个程序
我使用OpenSSL(在C中)对文本进行签名,但是我的Java程序并不总是验证签名的消息(只有大约1/5得到验证)。有趣的是,https://kjur.github.io/jsrsasign/sample/sample-ecdsa.html没有证实其中任何一个: 曲线名称:secp256k1签名算法:SHA256with ECDSA 私钥 密钥 失败: 成功: 爪哇 C.