java - Java keystore 中的 Lazysodium key

标签 java cryptography keystore libsodium ed25519

我正在使用 Lazysodium 库 ( https://terl.gitbook.io/lazysodium/ ) 从 Java 访问 libsodium,专门用于 Ed25519 数字签名。

我还希望能够将 key 对存储在标准 Java keystore 中。但是,libsodium 使用字节数组而不是 JCA Keypair 实例,因此尚不清楚如何实现这一点。

特别是,您如何:

  • 将 Libsodium 使用的字节数组 Ed25519 key 转换为 JCA key 对?
  • 将 JCA key 对转换回 libsodium 的适当字节数组?

最佳答案

原始私有(private) Ed25519 key 和 java.security.PrivateKey 之间的转换是可能的,例如BouncyCaSTLe 如下:

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.KeyFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
import org.bouncycastle.crypto.util.PrivateKeyFactory;
import org.bouncycastle.util.encoders.Hex;

...
// Generate private test key
PrivateKey privateKey = loadPrivateKey("Ed25519");
byte[] privateKeyBytes = privateKey.getEncoded();
System.out.println(Base64.getEncoder().encodeToString(privateKeyBytes)); // PKCS#8-key, check this in an ASN.1 Parser, e.g. https://lapo.it/asn1js/

// java.security.PrivateKey to raw Ed25519 key
Ed25519PrivateKeyParameters ed25519PrivateKeyParameters = (Ed25519PrivateKeyParameters)PrivateKeyFactory.createKey(privateKeyBytes);
byte[] rawKey = ed25519PrivateKeyParameters.getEncoded();
System.out.println(Hex.toHexString(rawKey)); // equals the raw 32 bytes key from the PKCS#8 key

// Raw Ed25519 key to java.security.PrivateKey
KeyFactory keyFactory = KeyFactory.getInstance("Ed25519");
PrivateKeyInfo privateKeyInfo = new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), new DEROctetString(rawKey));
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKeyInfo.getEncoded());
PrivateKey privateKeyReloaded = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
byte[] privateKeyBytesReloaded = privateKeyReloaded.getEncoded();
System.out.println(Base64.getEncoder().encodeToString(privateKeyBytesReloaded)); // equals the PKCS#8 key from above

私钥是通过以下方式生成的:

private static PrivateKey loadPrivateKey(String algorithm) throws Exception {
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
    KeyPair keyPair = keyPairGenerator.generateKeyPair();
    return keyPair.getPrivate();
}

对于 X25519 类似,将所有 Ed25519 替换为 X25519

原始公共(public) X25519 key 和 java.security.PublicKey 之间的转换(反之亦然)可以在 here 中找到。 。对于原始公钥 Ed25519 key ,过程类似,其中每个 X25519 必须替换为 Ed25519

但是,我还没有测试Ed25519或X25519 key 是否可以存储在 keystore 中。

关于java - Java keystore 中的 Lazysodium key ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68480995/

相关文章:

java - 在eclipse中设置异常断点时忽略库

c# - 导入 RSA CngKey 并存储在 MicrosoftSoftwareKeyStorageProvider 中

c - 如何提供 OpenSSL 随机数据以用于 ECDSA 签名?

javascript - 即使使用 webcrypto-shim,crypto.subtle 也不存在

tomcat - 无法使用 JDK6 生成 keystore ,但可以使用 JDK5 生成

c++ - 使用不可导出的私钥和 CryptoAPI 进行解密

java - 解决 Java 中时间错误的错误格式?

java - 使用合成器自定义外观 JPogressBar 和 JSplitPane xml

java - 在对象中设置字节字段

http - CFHTTP 不通过 SSL 连接进行连接?