使用 Java 使用 Luna HSM 的 EDDSA 签名
EDDSA Signature with Luna HSM using Java
我正在尝试使用 Luna HSM(Gemalto) 实现 EDDSA 签名
Signature signature = null;
signature = Signature.getInstance("EDDSA", "LunaProvider");
PrivateKey privateKey = getPrivateByAlias(privateKeyLabel);
signature.initSign(privateKey);
signature.update(payload);
byte[] byteArray = signature.sign();
但是在签名之后,byteArray 大小为 71,但 EDDSA 签名大小为 64,按照规范。我不确定我在这里错过了什么。
我在网上也找不到任何文件。
这正是 X9.63 兼容签名所期望的大小,它由两个带符号的大端整数的 DER 编码组成。如果你想要一个 64 字节的签名那么你应该使用 the following explanation. An implementation in Java of I2OSP and OS2IP can be found here.
转换里面的 2 个整数
所以步骤是:
- 解析 ASN.1 签名;
- 使用
new BigInteger(byte[])
构造函数转换为 BigInteger
值;
- 使用 I2OSP 将 r 和 s 值创建为字节数组(32 个八位字节输出大小);
- 连接 r 和 s 以创建 64 字节签名。
我试过如下但验证失败(代码已更新,现在可以使用)
Signature signature = Signature.getInstance("SHA512withEDDSA", "LunaProvider");
signature.setParameter(new LunaEDDSAParameterSpec(false));
signature.initSign(privateKey);
signature.update(payload);
byte[] byteArray = signature.sign();
ASN1InputStream decoder = new ASN1InputStream(byteArray);
DERSequence seq = (DERSequence) decoder.readObject();
DERInteger r = (DERInteger) seq.getObjectAt(0);
DERInteger s = (DERInteger) seq.getObjectAt(1);
LOGGER.info("R: {}", r.getValue());
LOGGER.info("S: {}", s.getValue());
decoder.close();
byte[] rByte = i2osp(r.getValue(), 32);
byte[] sByte = i2osp(s.getValue(), 32);
byte[] concat = Bytes.concat(rByte, sByte);
return concat;
不确定这是正确的做法
使用stellar java库进行验证
PublicKey publicKey = getPublicByAlias(publicKeyLabel);
LunaPublicKeyEC lunaPublicKeyEC = (LunaPublicKeyEC) publicKey;
byte[] pubKeySub = Arrays.copyOfRange(lunaPublicKeyEC.getP(), 2, lunaPublicKeyEC.getP().length);
org.stellar.sdk.KeyPair keyPair = org.stellar.sdk.KeyPair.fromPublicKey(pubKeySub);
boolean verified = keyPair.verify(payload, signatureByte);
我正在尝试使用 Luna HSM(Gemalto) 实现 EDDSA 签名
Signature signature = null;
signature = Signature.getInstance("EDDSA", "LunaProvider");
PrivateKey privateKey = getPrivateByAlias(privateKeyLabel);
signature.initSign(privateKey);
signature.update(payload);
byte[] byteArray = signature.sign();
但是在签名之后,byteArray 大小为 71,但 EDDSA 签名大小为 64,按照规范。我不确定我在这里错过了什么。 我在网上也找不到任何文件。
这正是 X9.63 兼容签名所期望的大小,它由两个带符号的大端整数的 DER 编码组成。如果你想要一个 64 字节的签名那么你应该使用 the following explanation. An implementation in Java of I2OSP and OS2IP can be found here.
转换里面的 2 个整数所以步骤是:
- 解析 ASN.1 签名;
- 使用
new BigInteger(byte[])
构造函数转换为BigInteger
值; - 使用 I2OSP 将 r 和 s 值创建为字节数组(32 个八位字节输出大小);
- 连接 r 和 s 以创建 64 字节签名。
我试过如下但验证失败(代码已更新,现在可以使用)
Signature signature = Signature.getInstance("SHA512withEDDSA", "LunaProvider");
signature.setParameter(new LunaEDDSAParameterSpec(false));
signature.initSign(privateKey);
signature.update(payload);
byte[] byteArray = signature.sign();
ASN1InputStream decoder = new ASN1InputStream(byteArray);
DERSequence seq = (DERSequence) decoder.readObject();
DERInteger r = (DERInteger) seq.getObjectAt(0);
DERInteger s = (DERInteger) seq.getObjectAt(1);
LOGGER.info("R: {}", r.getValue());
LOGGER.info("S: {}", s.getValue());
decoder.close();
byte[] rByte = i2osp(r.getValue(), 32);
byte[] sByte = i2osp(s.getValue(), 32);
byte[] concat = Bytes.concat(rByte, sByte);
return concat;
不确定这是正确的做法
使用stellar java库进行验证
PublicKey publicKey = getPublicByAlias(publicKeyLabel);
LunaPublicKeyEC lunaPublicKeyEC = (LunaPublicKeyEC) publicKey;
byte[] pubKeySub = Arrays.copyOfRange(lunaPublicKeyEC.getP(), 2, lunaPublicKeyEC.getP().length);
org.stellar.sdk.KeyPair keyPair = org.stellar.sdk.KeyPair.fromPublicKey(pubKeySub);
boolean verified = keyPair.verify(payload, signatureByte);