Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用EdDSA/Ed448签名算法重新生成私钥?_Java_Cryptography_Digital Signature_Java 15_Eddsa - Fatal编程技术网

Java 如何使用EdDSA/Ed448签名算法重新生成私钥?

Java 如何使用EdDSA/Ed448签名算法重新生成私钥?,java,cryptography,digital-signature,java-15,eddsa,Java,Cryptography,Digital Signature,Java 15,Eddsa,下面是我如何生成密钥对的: var keyPairGenerator = KeyPairGenerator.getInstance("Ed448"); keyPairGenerator.initialize(448, SecureRandom.getInstanceStrong()); var keyPair = keyPairGenerator.generateKeyPair(); var privateKey = keyPair.getPrivate(); var pub

下面是我如何生成密钥对的:

var keyPairGenerator = KeyPairGenerator.getInstance("Ed448");
keyPairGenerator.initialize(448, SecureRandom.getInstanceStrong());
var keyPair = keyPairGenerator.generateKeyPair();
var privateKey = keyPair.getPrivate();
var publicKey = keyPair.getPublic();
byte[] privateKeyBytes = privateKey.getEncoded();
byte[] publicKeyBytes = publicKey.getEncoded();
但是,当我再次尝试重新生成密钥时,出现了一个异常:

var keyFactory = KeyFactory.getInstance("EdDSA");
var edECPoint = byteArrayToEdPoint(publicKeyBytes);
var edECPublicKeySpec = new EdECPublicKeySpec(new NamedParameterSpec("Ed448"), edECPoint);
var publicKey = keyFactory.generatePublic(edECPublicKeySpec);
var edECPrivateKeySpec = new EdECPrivateKeySpec(new NamedParameterSpec("Ed448"), privateKeyBytes);
var privateKey = keyFactory.generatePrivate(edECPrivateKeySpec); // generatePrivate() throws exception
异常堆栈跟踪:

Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: key length is 73, key length must be 57
    at jdk.crypto.ec/sun.security.ec.ed.EdDSAKeyFactory.engineGeneratePrivate(EdDSAKeyFactory.java:129)
    at java.base/java.security.KeyFactory.generatePrivate(KeyFactory.java:390)
    at io.fouad.Main.main(Main.java:48)
Caused by: java.security.InvalidKeyException: key length is 73, key length must be 57
    at jdk.crypto.ec/sun.security.ec.ed.EdDSAPrivateKeyImpl.checkLength(EdDSAPrivateKeyImpl.java:84)
    at jdk.crypto.ec/sun.security.ec.ed.EdDSAPrivateKeyImpl.<init>(EdDSAPrivateKeyImpl.java:61)
    at jdk.crypto.ec/sun.security.ec.ed.EdDSAKeyFactory.generatePrivateImpl(EdDSAKeyFactory.java:171)
    at jdk.crypto.ec/sun.security.ec.ed.EdDSAKeyFactory.engineGeneratePrivate(EdDSAKeyFactory.java:127)
    ... 2 more
下面是我从中复制的一些实用程序:

由于privateKey.GetEncodedT实例将为EdDSAPrivateKeyImpl类型,并将返回PKCS8格式的密钥,因此应使用PKCS8EncodedKeySpec:

否则,您必须自己打开序列并获取PrivateKey,这是OctetString,如中所述。然后,您可以使用EdECPrivateKeySpec。

由于privateKey.getEncodedT实例将为EdDSAPrivateKeyImpl类型,并且将返回PKCS8格式的密钥,因此您应该使用PKCS8EncodedKeySpec:


否则,您必须自己打开序列并获取PrivateKey,这是OctetString,如中所述。然后您可以使用EdECPrivateKeySpec。

您尝试过票证的示例吗?@flaxel该示例仅用于重新生成公钥,并且使用Ed25519而不是Ed448。使用PKCS8EncodedKeySpec PKCS8EncodedKeySpec=new PKCS8EncodedKeySpecprivateKeyBytes;把它交给钥匙厂。generatePrivate@michalkPKCS8EncodedKeySpec用于生成RSA私钥。我不确定这样做是否正确。PKCS8是描述私钥格式的标准。它不仅可以表示RSA密钥……您是否尝试过该票证的示例?@flaxel该示例仅用于重新生成公钥,并且使用Ed25519而不是Ed448。请使用PKCS8EncodedKeySpec PKCS8EncodedKeySpec=new PKCS8EncodedKeySpecprivateKeyBytes;把它交给钥匙厂。generatePrivate@michalkPKCS8EncodedKeySpec用于生成RSA私钥。我不确定这样做是否正确。PKCS8是描述私钥格式的标准。它不仅可以代表RSA密钥…+1感谢您的帮助。实际上,我通过调用EdECPrivateKey keyPair.getPrivate.getBytes.OrelsThrow来实现它。如果您已经有EdECPrivateKey的实例,这将起作用,但是,如果您想从包含PKCS8格式密钥的文本文件中重建它,您将无法执行此操作。EdecPrivate keyPair.getPrivate.getBytes.OrelsThrow将返回一个字节数组,然后我可以像这样使用它:new EdecPrivate KeySpecNamedParameterSpec.ED448,byteArray;。但是,byteArrayToEdPoint似乎工作不正常,我在进行验证时发现y值太大:我将尝试查看它。我最终使用了keyFactory.generatePublicnew X509EncodedKeySpecpublicKey.getEncoded和keyFactory.generatePrivatenew PKCS8EncodedKeySpecprivateKey.getEncoded。再次感谢你的帮助。实际上,我通过调用EdECPrivateKey keyPair.getPrivate.getBytes.OrelsThrow来实现它。如果您已经有EdECPrivateKey的实例,这将起作用,但是,如果您想从包含PKCS8格式密钥的文本文件中重建它,您将无法执行此操作。EdecPrivate keyPair.getPrivate.getBytes.OrelsThrow将返回一个字节数组,然后我可以像这样使用它:new EdecPrivate KeySpecNamedParameterSpec.ED448,byteArray;。但是,byteArrayToEdPoint似乎工作不正常,我在进行验证时发现y值太大:我将尝试查看它。我最终使用了keyFactory.generatePublicnew X509EncodedKeySpecpublicKey.getEncoded和keyFactory.generatePrivatenew PKCS8EncodedKeySpecprivateKey.getEncoded。再次感谢。
private static EdECPoint byteArrayToEdPoint(byte[] arr)
{
    byte msb = arr[arr.length - 1];
    boolean xOdd = (msb & 0x80) != 0;
    arr[arr.length - 1] &= (byte) 0x7F;
    reverse(arr);
    BigInteger y = new BigInteger(1, arr);
    return new EdECPoint(xOdd, y);
}

private static void reverse(byte [] arr)
{
    int i = 0;
    int j = arr.length - 1;
    
    while(i < j)
    {
        swap(arr, i, j);
        i++;
        j--;
    }
}

private static void swap(byte[] arr, int i, int j)
{
    byte tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
var keyFactory = KeyFactory.getInstance("EdDSA");
var pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
var privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);