标签: ecdsa

Ruby/openssl:将椭圆曲线点八位字节串转换为OpenSSL :: PKey :: EC :: Point

我正在尝试编写Ruby代码来检查我在此处找到的特定消息上的椭圆曲线数字签名算法(ECDSA)签名.

问题是我不知道如何将公钥的八位字节串转换为OpenSSL :: PKey :: EC :: Point对象.如果我用C语言写这个,我只是将八位字节字符串传递给OpenSSL o2i_ECPublicKey,它做了一些接近我想要的东西,实际上是由参考实现使用的.但是,我搜索了Ruby(MRI)源代码并且它不包含任何调用,o2i_ECPublicKey因此我不知道如何在不编写C扩展的情况下从Ruby中使用该函数.

这是十六进制的八位字符串.它只是一个0x04字节,后跟两个32字节整数,表示椭圆曲线上点的x和y坐标:

04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284
Run Code Online (Sandbox Code Playgroud)

那么有谁知道如何将该字符串转换为OpenSSL::PKey::EC::PointRuby 中的in?一旦我得到了点对象,我将在下面的代码中使用它,我认为这将验证签名:

key = OpenSSL::PKey::EC.new('secp256k1')
key.public_key = point
result = key.dsa_verify_asn1(digest, signature)
Run Code Online (Sandbox Code Playgroud)

更新:

感谢Jay-Ar Polidario,我得到了它的工作.以下是我使用OpenSSL验证签名的完整代码.我还写了一个名为ecdsa的宝石,我包含的代码显示了如何使用我的宝石做同样的事情.

# coding: ASCII-8BIT

digest =
  "\xbf\x91\xfb\x0b\x4f\x63\x33\x77\x4a\x02\x2b\xd3\x07\x8e\xd6\xcc" \
  "\xd1\x76\xee\x31\xed\x4f\xb3\xf9\xaf\xce\xb7\x2a\x37\xe7\x87\x86"

signature_der_string =
  "\x30\x45" \
  "\x02\x21\x00" \
  "\x83\x89\xdf\x45\xf0\x70\x3f\x39\xec\x8c\x1c\xc4\x2c\x13\x81\x0f" \
  "\xfc\xae\x14\x99\x5b\xb6\x48\x34\x02\x19\xe3\x53\xb6\x3b\x53\xeb" \
  "\x02\x20" \
  "\x09\xec\x65\xe1\xc1\xaa\xee\xc1\xfd\x33\x4c\x6b\x68\x4b\xde\x2b" \
  "\x3f\x57\x30\x60\xd5\xb7\x0c\x3a\x46\x72\x33\x26\xe4\xe8\xa4\xf1"

public_key_octet_string =
  "\x04" \
  "\xfc\x97\x02\x84\x78\x40\xaa\xf1\x95\xde\x84\x42\xeb\xec\xed\xf5" \
  "\xb0\x95\xcd\xbb\x9b\xc7\x16\xbd\xa9\x11\x09\x71\xb2\x8a\x49\xe0" \
  "\xea\xd8\x56\x4f\xf0\xdb\x22\x20\x9e\x03\x74\x78\x2c\x09\x3b\xb8" \
  "\x99\x69\x2d\x52\x4e\x9d\x6a\x69\x56\xe7\xc5\xec\xbc\xd6\x82\x84"

# Verifying with …
Run Code Online (Sandbox Code Playgroud)

ruby openssl elliptic-curve ecdsa

9
推荐指数
1
解决办法
2636
查看次数

使用BouncyCastle验证Java中的ECDSA签名时出错

我已经测试了一个解决方案,以验证ECDSA签名(如何从EC公钥字节中获取PublicKey对象?),它与给定数据完美配合.

这是数据:

byte[] pubKey = DatatypeConverter.parseHexBinary("049a55ad1e210cd113457ccd3465b930c9e7ade5e760ef64b63142dad43a308ed08e2d85632e8ff0322d3c7fda14409eafdc4c5b8ee0882fe885c92e3789c36a7a");
byte[] message = DatatypeConverter.parseHexBinary("54686973206973206a75737420736f6d6520706f696e746c6573732064756d6d7920737472696e672e205468616e6b7320616e7977617920666f722074616b696e67207468652074696d6520746f206465636f6465206974203b2d29");
byte[] signature = DatatypeConverter.parseHexBinary("304402205fef461a4714a18a5ca6dce6d5ab8604f09f3899313a28ab430eb9860f8be9d602203c8d36446be85383af3f2e8630f40c4172543322b5e8973e03fff2309755e654");
Run Code Online (Sandbox Code Playgroud)

这是代码(打印为true):

private static boolean isValidSignature(byte[] pubKey, byte[] message,byte[] signature) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException, InvalidKeySpecException {
    Signature ecdsaVerify = Signature.getInstance("SHA256withECDSA", new BouncyCastleProvider());
    ecdsaVerify.initVerify(getPublicKeyFromBytes(pubKey));
    ecdsaVerify.update(message);
    return ecdsaVerify.verify(signature);
}

private static PublicKey getPublicKeyFromBytes(byte[] pubKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
    ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("prime256v1");
    KeyFactory kf = KeyFactory.getInstance("ECDSA", new BouncyCastleProvider());
    ECNamedCurveSpec params = new ECNamedCurveSpec("prime256v1", spec.getCurve(), spec.getG(), spec.getN());
    ECPoint point =  ECPointUtil.decodePoint(params.getCurve(), pubKey);
    ECPublicKeySpec pubKeySpec = …
Run Code Online (Sandbox Code Playgroud)

java bouncycastle signature ecdsa

9
推荐指数
1
解决办法
5428
查看次数

未知的116字节ECDSA私钥格式

iOS 13的CryptoKit框架.rawRepresentation为ECDSA公钥和私钥提供了价值。我一直在尝试对rawRepresentation数据类型进行逆向工程,以便在它与JWK之间进行转换。从公钥表示形式的64字节长度来看,这似乎是一个简单的x || y串联。我猜想那会是私钥x || y || d,但是事实并非如此,因为这样做应该会产生96字节的字符串,而实际rawRepresentation144字节。似乎也不是有效的DER / ASN.1字符串。我还没有找到符合我所得到的实际值的规格。

如您所料,Apple的文档具有很强的描述性。

rawRepresentation:私钥的表示形式,以字节的集合表示。

提供了十六进制的示例密钥对。

Private: 988f8187ff7f00007466815b0d6b02ae1a063198fd1e4923fb1e413195126cc00d30483284186b435726c0c69cc774274ea32eb6a17cbaf2ea88dd7f3a5a2a3ce637bc4b96523c2795035bd2fbeb093b010000000000000000000000000000000000000000000000000000000000000012b2b61abe8beae5aeb6d0bda739235364de96c7f498813cfb0336198dcf9063
Public:  2774c79cc6c02657436b18843248300dc06c129531411efb23491efd9831061a3b09ebfbd25b0395273c52964bbc37e63c2a5a3a7fdd88eaf2ba7ca1b62ea34e
Run Code Online (Sandbox Code Playgroud)

这是什么格式?

binary-data key-pair ecdsa swift apple-cryptokit

9
推荐指数
1
解决办法
137
查看次数

从私钥导出 ECDSA 公钥

我试图从私钥生成公共 ECDSA 密钥,但我没有在互联网上找到太多关于如何执行此操作的帮助。几乎所有东西都是为了从公钥规范生成公钥,我不知道如何获得它。到目前为止,这是我整理的内容:

public void setPublic() throws GeneralSecurityException {
    ECNamedCurveParameterSpec params = ECNamedCurveTable.getParameterSpec("secp256k1");
    KeyFactory fact = KeyFactory.getInstance("ECDSA", "BC");
    ECCurve curve = params.getCurve();
    java.security.spec.EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, params.getSeed());
    java.security.spec.ECPoint point = ECPointUtil.decodePoint(ellipticCurve, this.privateKey.getEncoded());
    java.security.spec.ECParameterSpec params2=EC5Util.convertSpec(ellipticCurve, params);
    java.security.spec.ECPublicKeySpec keySpec = new java.security.spec.ECPublicKeySpec(point,params2);
    this.publicKey = fact.generatePublic(keySpec);
}
Run Code Online (Sandbox Code Playgroud)

但是,在运行时,我收到以下错误:

Exception in thread "main" java.lang.IllegalArgumentException: Invalid point encoding 0x30
at org.bouncycastle.math.ec.ECCurve.decodePoint(Unknown Source)
at org.bouncycastle.jce.ECPointUtil.decodePoint(Unknown Source)
at Wallet.Wallet.setPublic(Wallet.java:125)
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?有没有更好/更简单的方法来做到这一点?

编辑:我已经设法编译了一些代码,但它不能正常工作:

public void setPublic() throws GeneralSecurityException {
    BigInteger privKey = new BigInteger(getHex(privateKey.getEncoded()),16);
    X9ECParameters ecp = SECNamedCurves.getByName("secp256k1");
    ECPoint …
Run Code Online (Sandbox Code Playgroud)

java cryptography bouncycastle ecdsa

8
推荐指数
1
解决办法
7911
查看次数

Xcode 无法处理密钥加密 Ed25519

这不仅仅是一个问题,更是一个分享信息的帖子。

如果您通过 SSH 拉取私有存储库,则应该创建一个id_ecdsa,因为 Xcode 不接受 Ed25519 密钥,而是因为 github 从昨天起不再接受 RSA-SHA1。

https://github.blog/2021-09-01-improving-git-protocol-security-github/

要生成它,请使用:ssh-keygen -t ecdsa -C "your_email@example.com"

您可以从此处执行后续配置步骤:https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generate-a-new-ssh-key-and-adding-it -to-the-ssh-agent#将您的 ssh-key 添加到-the-ssh-agent

ssh xcode github ecdsa

8
推荐指数
1
解决办法
2253
查看次数

如何使用golang加密写出ecdsa密钥?

我有一些Go代码生成一个ECDSA密钥并将其写入文件:

priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
ecder, err := x509.MarshalECPrivateKey(priv)
keypem, err := os.OpenFile("ec-key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
pem.Encode(keypem, &pem.Block{Type: "EC PRIVATE KEY", Bytes: ecder})
Run Code Online (Sandbox Code Playgroud)

这适用于并生成"BEGIN EC PRIVATE KEY"块.但是当你在openssl中写出密钥时,你也会得到一个"BEGIN EC PARAMETERS"块,指定使用的曲线.有没有办法将EC参数写入Go中的pem文件?

cryptography go ecdsa

7
推荐指数
1
解决办法
2759
查看次数

如何使用海绵城堡为比特币曲线(secp256k1)创建ECDSA密钥对(256位)?

目前,当我使用以下方法创建密钥时

private  KeyPair getKeyPair() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
    KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDsA", "SC");
    ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256k1");
    keyGen.initialize(ecSpec, new SecureRandom());
    return keyGen.generateKeyPair();
}
Run Code Online (Sandbox Code Playgroud)

KeyPairGenerator有另一种方法,我可以在其中指定keySize,但我不知道如何通过ecSpec.

 public void initialize(int keysize, SecureRandom random)
Run Code Online (Sandbox Code Playgroud)

java encryption android bouncycastle ecdsa

7
推荐指数
1
解决办法
5542
查看次数

使用Node.js/crypto生成ECDSA签名

我有使用jsrsasignJKK格式的密钥为ECDSA签名生成连接(rs)签名的代码:

const sig = new Signature({ alg: 'SHA256withECDSA' });
sig.init(KEYUTIL.getKey(key));
sig.updateHex(dataBuffer.toString('hex'));
const asn1hexSig = sig.sign();
const concatSig = ECDSA.asn1SigToConcatSig(asn1hexSig);
return new Buffer(concatSig, 'hex');
Run Code Online (Sandbox Code Playgroud)

似乎工作.我也有SubtleCrypto用于实现同样的事情的代码:

importEcdsaKey(key, 'sign') // importKey JWK -> raw
.then((privateKey) => subtle.sign(
    { name: 'ECDSA', hash: {name: 'SHA-256'} },
    privateKey,
    dataBuffer
))
Run Code Online (Sandbox Code Playgroud)

这两个都返回128字节的缓冲区; 并且他们交叉验证(即我可以验证jsrsasign签名,SubtleCrypto反之亦然).但是,当我Sign在Node.js crypto模块中使用该类时,我似乎得到了一些完全不同的东西.

key = require('jwk-to-pem')(key, {'private': true});
const sign = require('crypto').createSign('sha256');
sign.update(dataBuffer);
return sign.sign(key);
Run Code Online (Sandbox Code Playgroud)

这里我得到一个可变长度的缓冲区,大约70个字节; 它没有交叉验证jsrsa(抱怨rs签名的长度无效).

我怎样才能得到一个RS签名,通过所产生jsrsasignSubtleCrypto使用节点crypto …

cryptography node.js ecdsa

7
推荐指数
1
解决办法
5383
查看次数

Java - 使用ECDSA创建XML数字签名(椭圆曲线)

我们可以使用RSA密钥创建XML数字签名.但是如何使用椭圆曲线键来签署xml文件?我收到错误消息,如 -

Exception in thread "main" java.security.KeyException: ECKeyValue not supported
    at org.jcp.xml.dsig.internal.dom.DOMKeyValue$EC.<init>(DOMKeyValue.java:350)
    at org.jcp.xml.dsig.internal.dom.DOMKeyInfoFactory.newKeyValue(DOMKeyInfoFactory.java:71)
    at csr.ExtractEC.main(XMLSignatureECTest.java:57)
Caused by: java.lang.ClassNotFoundException: sun/security/ec/ECParameters
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at org.jcp.xml.dsig.internal.dom.DOMKeyValue$EC.getMethods(DOMKeyValue.java:367)
    at org.jcp.xml.dsig.internal.dom.DOMKeyValue$EC$1.run(DOMKeyValue.java:343)
    at org.jcp.xml.dsig.internal.dom.DOMKeyValue$EC$1.run(DOMKeyValue.java:339)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.jcp.xml.dsig.internal.dom.DOMKeyValue$EC.<init>(DOMKeyValue.java:338)
    ... 2 more
Run Code Online (Sandbox Code Playgroud)

我用下面的代码创建了SignatureMethod和KeyInfo -

String url = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256";
        SignatureMethod signatureMethod = factory.newSignatureMethod(url, null);
        SignedInfo signedInfo = factory.newSignedInfo(c14n, signatureMethod, Collections.singletonList(reference));

        PrivateKey privateKey = Utils.generatePrivateEC("e:\\certs\\ec\\ec.key.p8");
        Certificate certificate = Utils.generatePublic("e:\\certs\\ec\\ec.cer");
        KeyInfoFactory keyInfoFactory = factory.getKeyInfoFactory();
        KeyValue keyValue = keyInfoFactory.newKeyValue(certificate.getPublicKey());
        KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(keyValue));
Run Code Online (Sandbox Code Playgroud)

JDK - Oracle JDK …

java digital-signature elliptic-curve xml-dsig ecdsa

7
推荐指数
1
解决办法
502
查看次数

Create EC private key from hex string

I am wondering if this is a correct way to create PrivateKey object in Java from HEX string from this website: https://kjur.github.io/jsrsasign/sample/sample-ecdsa.html

Create a BigInteger from a HEX String:

BigInteger priv = new BigInteger(privateKeyFromSite, 16);
Run Code Online (Sandbox Code Playgroud)

And pass to this method:

import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;

import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPrivateKeySpec;


public static PrivateKey getPrivateKeyFromECBigIntAndCurve(BigInteger s, String curveName) {

    ECParameterSpec ecParameterSpec = ECNamedCurveTable.getParameterSpec(curveName);

    ECPrivateKeySpec privateKeySpec = new ECPrivateKeySpec(s, ecParameterSpec);
    try {
        KeyFactory keyFactory = KeyFactory.getInstance(EC); …
Run Code Online (Sandbox Code Playgroud)

java bouncycastle elliptic-curve ecdsa

7
推荐指数
1
解决办法
4428
查看次数