- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Bouncy CaSTLe 的最新(测试版)版本 (bcprov-jdk15on-161b20.jar) 支持用于签名目的的 ED25519 和 ED448 EC 加密。我设置了这个完整的工作示例,它按预期工作。
我的问题:我是否正确重建了私钥和公钥,因为我没有在 bc-tests 中找到任何示例?我预计我必须使用一些规范功能,如“X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(content)”来重建 RSA key ,但我的代码正在运行。
package bc;
// original source: https://github.com/bcgit/bc-java/blob/master/core/src/test/java/org/bouncycastle/crypto/test/Ed25519Test.java
// needs bouncy castle beta: bcprov-jdk15on-161b20.jar (version 1.605)
// tested with Java 8 Build 191 x64
// this is a full working example for generating, signing, verififying with ed25519 keys
// code: https://github.com/java-crypto/Bouncy-Castle
import java.security.Provider;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Arrays;
import java.io.UnsupportedEncodingException;
import javax.xml.bind.DatatypeConverter;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.CryptoException;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.Signer;
import org.bouncycastle.crypto.generators.Ed25519KeyPairGenerator;
import org.bouncycastle.crypto.params.Ed25519KeyGenerationParameters;
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
import org.bouncycastle.crypto.signers.Ed25519Signer;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class Ed25519Bc {
public static void main(String[] args) throws DataLengthException, CryptoException, UnsupportedEncodingException {
System.out.println("ED25519 with BC");
Security.addProvider(new BouncyCastleProvider());
Provider provider = Security.getProvider("BC");
System.out.println("Provider :" + provider.getName() + " Version: " + provider.getVersion());
// generate ed25519 keys
SecureRandom RANDOM = new SecureRandom();
Ed25519KeyPairGenerator keyPairGenerator = new Ed25519KeyPairGenerator();
keyPairGenerator.init(new Ed25519KeyGenerationParameters(RANDOM));
AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair();
Ed25519PrivateKeyParameters privateKey = (Ed25519PrivateKeyParameters) asymmetricCipherKeyPair.getPrivate();
Ed25519PublicKeyParameters publicKey = (Ed25519PublicKeyParameters) asymmetricCipherKeyPair.getPublic();
// the message
byte[] message = "Message to sign".getBytes("utf-8");
// create the signature
Signer signer = new Ed25519Signer();
signer.init(true, privateKey);
signer.update(message, 0, message.length);
byte[] signature = signer.generateSignature();
// verify the signature
Signer verifier = new Ed25519Signer();
verifier.init(false, publicKey);
verifier.update(message, 0, message.length);
boolean shouldVerify = verifier.verifySignature(signature);
// output
byte[] privateKeyEncoded = privateKey.getEncoded();
byte[] publicKeyEncoded = publicKey.getEncoded();
System.out.println("privateKey Length :" + privateKeyEncoded.length + " Data:"
+ DatatypeConverter.printHexBinary(privateKeyEncoded));
System.out.println("publicKey Length :" + publicKeyEncoded.length + " Data:"
+ DatatypeConverter.printHexBinary(publicKeyEncoded));
System.out.println(
"signature Length :" + signature.length + " Data:" + DatatypeConverter.printHexBinary(signature));
System.out.println("signature correct :" + shouldVerify);
// rebuild the keys
System.out.println("Rebuild the keys and verify the signature with rebuild public key");
Ed25519PrivateKeyParameters privateKeyRebuild = new Ed25519PrivateKeyParameters(privateKeyEncoded, 0);
Ed25519PublicKeyParameters publicKeyRebuild = new Ed25519PublicKeyParameters(publicKeyEncoded, 0);
byte[] privateKeyRebuildEncoded = privateKeyRebuild.getEncoded();
System.out.println("privateKey Length :" + privateKeyRebuild.getEncoded().length + " Data:"
+ DatatypeConverter.printHexBinary(privateKeyRebuild.getEncoded()));
byte[] publicKeyRebuildEncoded = publicKeyRebuild.getEncoded();
System.out.println("publicKey Length :" + publicKeyRebuild.getEncoded().length + " Data:"
+ DatatypeConverter.printHexBinary(publicKeyRebuild.getEncoded()));
// compare the keys
System.out.println("private Keys Equal:" + Arrays.equals(privateKeyEncoded, privateKeyRebuildEncoded));
System.out.println("public Keys Equal :" + Arrays.equals(publicKeyEncoded, publicKeyRebuildEncoded));
// verify the signature with rebuild public key
Signer verifierRebuild = new Ed25519Signer();
verifierRebuild.init(false, publicKeyRebuild);
verifierRebuild.update(message, 0, message.length);
boolean shouldVerifyRebuild = verifierRebuild.verifySignature(signature);
System.out.println("signature correct :" + shouldVerifyRebuild + " with rebuild public key");
}
}
这是显示正确重建 key 的控制台输出:
ED25519 with BC
Provider :BC Version: 1.605
privateKey Length :32 Data:F6A1F3A0B8F44EE64ACE636AFCA262F656160A728C042E3F98F9A0FD45717DE7
publicKey Length :32 Data:858C2D6D5910B8AA7B52F7DF8E5806DAD3A7E43DC19C5A548F241BD8B82510FE
signature Length :64 Data:4D402B0095F6692742DCACB0C2C39BFB70A5687F162DFAB3721A660D2259C96B972DF41B97502347E534FAD8D59496811CDFFFA831264ECBB1429439CF350E08
signature correct :true
Rebuild the keys and verify the signature with rebuild public key
privateKey Length :32 Data:F6A1F3A0B8F44EE64ACE636AFCA262F656160A728C042E3F98F9A0FD45717DE7
publicKey Length :32 Data:858C2D6D5910B8AA7B52F7DF8E5806DAD3A7E43DC19C5A548F241BD8B82510FE
private Keys Equal:true
public Keys Equal :true
signature correct :true with rebuild public key
最佳答案
我也在研究 Ed25519,所以我一直在研究 BouncyCaSTLe 的实现以及 Tink 和 libsodium;我当然看不出你如何重建 key 对有什么问题,这似乎与 BouncyCaSTLe 在其他地方使用它的方式一致:OpenSSHPrivateKeyUtil和 Ed25519Test .
import org.bouncycastle.crypto.CryptoException;
import org.bouncycastle.crypto.Signer;
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
import org.bouncycastle.crypto.signers.Ed25519Signer;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import static org.junit.Assert.assertEquals;
public class BouncyCastleTest {
private static final Logger LOG = LoggerFactory.getLogger(BouncyCastleTest.class);
@Test
public void testBouncyCastle() throws CryptoException {
// Test case defined in https://www.rfc-editor.org/rfc/rfc8037
var msg = "eyJhbGciOiJFZERTQSJ9.RXhhbXBsZSBvZiBFZDI1NTE5IHNpZ25pbmc".getBytes(StandardCharsets.UTF_8);
var expectedSig = "hgyY0il_MGCjP0JzlnLWG1PPOt7-09PGcvMg3AIbQR6dWbhijcNR4ki4iylGjg5BhVsPt9g7sVvpAr_MuM0KAg";
var privateKeyBytes = Base64.getUrlDecoder().decode("nWGxne_9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A");
var publicKeyBytes = Base64.getUrlDecoder().decode("11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo");
var privateKey = new Ed25519PrivateKeyParameters(privateKeyBytes, 0);
var publicKey = new Ed25519PublicKeyParameters(publicKeyBytes, 0);
// Generate new signature
Signer signer = new Ed25519Signer();
signer.init(true, privateKey);
signer.update(msg, 0, msg.length);
byte[] signature = signer.generateSignature();
var actualSignature = Base64.getUrlEncoder().encodeToString(signature).replace("=", "");
LOG.info("Expected signature: {}", expectedSig);
LOG.info("Actual signature : {}", actualSignature);
assertEquals(expectedSig, actualSignature);
}
}
您也可以使用 JCA 实现相同的目的,在此示例中,我的 key 对采用“原始”格式(即 X 和 D 坐标):
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.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.Security;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import static org.junit.Assert.assertEquals;
public class Ed25519JCA {
private static final Logger LOG = LoggerFactory.getLogger(Ed25519JCA.class);
@Test
public void testEd25519WithJCA() throws Exception {
Security.addProvider(new BouncyCastleProvider());
// Test case defined in https://www.rfc-editor.org/rfc/rfc8037
var msg = "eyJhbGciOiJFZERTQSJ9.RXhhbXBsZSBvZiBFZDI1NTE5IHNpZ25pbmc".getBytes(StandardCharsets.UTF_8);
var expectedSig = "hgyY0il_MGCjP0JzlnLWG1PPOt7-09PGcvMg3AIbQR6dWbhijcNR4ki4iylGjg5BhVsPt9g7sVvpAr_MuM0KAg";
// Both formatted as 32bit raw key values (x and d)
var privateKeyBytes = Base64.getUrlDecoder().decode("nWGxne_9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A");
var publicKeyBytes = Base64.getUrlDecoder().decode("11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo");
var keyFactory = KeyFactory.getInstance("Ed25519");
// Wrap public key in ASN.1 format so we can use X509EncodedKeySpec to read it
var pubKeyInfo = new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), publicKeyBytes);
var x509KeySpec = new X509EncodedKeySpec(pubKeyInfo.getEncoded());
var jcaPublicKey = keyFactory.generatePublic(x509KeySpec);
// Wrap private key in ASN.1 format so we can use
var privKeyInfo = new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), new DEROctetString(privateKeyBytes));
var pkcs8KeySpec = new PKCS8EncodedKeySpec(privKeyInfo.getEncoded());
var jcaPrivateKey = keyFactory.generatePrivate(pkcs8KeySpec);
// Generate new signature
var dsa = Signature.getInstance("EdDSA"); // Edwards digital signature algorithm
dsa.initSign(jcaPrivateKey);
dsa.update(msg, 0, msg.length);
byte[] signature = dsa.sign();
var actualSignature = Base64.getUrlEncoder().encodeToString(signature).replace("=", "");
LOG.info("Expected signature: {}", expectedSig);
LOG.info("Actual signature : {}", actualSignature);
assertEquals(expectedSig, actualSignature);
}
}
为了完整起见,您还可以首先使用 JCA 生成 key 对,这样可以避免大量的格式转换:
Security.addProvider(new BouncyCastleProvider());
var keyPair = KeyPairGenerator.getInstance("Ed25519").generateKeyPair();
关于java - 使用 Bouncy CaSTLe (Java) 重建 ED25519 key ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53921655/
For 循环和多个变量和条件。 我正在使用 for 循环来设置源索引和目标索引以复制数组中的项目。 for(int src = 0, dst = 8; src = 0; src ++,
我正在尝试创建一个 2 面的 ggplot 对象,并将它们 grid.arrange 在两列中(grid.arrange 列)。在第二列中,在每个分面成员中,我想插入一个直方图。两列的数据源也不同。到
我正在使用 MS VS2010 和一个名为 Deleaker 的插件来发现我可能错过的任何内存泄漏。它告诉我 fopen_s 行有 2 处内存泄漏,但我没有在该行的任何内容上使用 new 或 mall
java.nio.charset.Charset.forName("utf8").decode解码 的字节序列 ED A0 80 ED B0 80 进入 Unicode 代码点: U+10000
我必须国际化 (i18n) 一个 Django 项目。它结合了许多内部 django 应用程序。它已经部分国际化了,即一些字符串是 _(),但有些是空的。一些模板使用 {% blocktrans %}
什么是EDS和 OD ?它们是如何创建和使用的? OD 是如何介于应用程序和 CAN 之间的?界面? 最佳答案 首先你应该读一点关于CANopen的内容熟悉这些概念。检查www.canopen.de您
我正在浏览 Wikipedia/Restrict , 并发现 The compiler can e.g. rearrange the code, first loading all memory lo
我正在 Linux 中编写一个 bourne shell 脚本,我正在使用 ed 将文本附加到文件的末尾。 我必须使用 ed 来完成这项任务。 我需要附加的文字看起来像这样 Modified on:
考虑以下 IL 代码: .method public static void Main() { ldstr "Starts Here" call voi
我有这样的东西: //html Action 1 Action 1 Action 1 ...
考虑使用 malloc 定义的 (char *) 变量 sTmp, 如果我将另一个变量分配给此 sTmp,通过该变量分配的内存是否会自动释放,或者该内存块是否会保持分配(且无用)直到进程结束? 让我用
我定义了一个不透明的结构和相关的 API,如下所示: typedef struct foo foo; foo *create_foo(...); delete_foo(foo *f); 我无法在我的
使用以下伪 Python 脚本将数据发送到本地套接字: s = socket.socket(AF_UNIX, SOCK_STREAM) s.connect("./sock.sock") s.send(
我有一个正方形比例的MKMapView mainMap,它的宽度等于iPhone屏幕宽度。我使用以下方法将其设为圆形: mainMap.layer.cornerRadius = mainMap.fra
假设您要对所有包含模式的文件进行编辑。例如,将所有“2017”更改为“2018”。存在许多针对 perl、sed 和各种其他的建议。如果 ed 编辑器可以工作的话,它会简单得多。 给定一个文件: $
我在 bash 脚本中使用 ed 来搜索文件; / 命令将显示我不想要的内容。我尝试重定向 >/dev/null 2>&1 但这对我不起作用。 文本文件foo.txt: a b c bash 脚本ba
我正在研究 ed 文本编辑器。 要退出输入模式,用户应输入一个句点 (.)。 假设我想以文本形式输入句点。 我想到了一个解决方法:首先,我插入类似.. 的内容。然后,我将 .. 替换为 .. 但我的方
Rust playground : trait FnBox { fn call_box(self: Box); } impl FnBox for F { fn call_box(sel
我们有多个域指向我们的 Tomcat Web 应用程序,它们都由我们的默认 Host 提供服务: 我需要配置哪个 Valve 模式来查看请求已发送到哪个域(即用户在网络浏览器中输入了哪
我做了一个简单的test(jsbin)与: {a:1} //dummy value var a=1; 然后: alert($("#a").text()); 结果是: 但是 - 使用
我是一名优秀的程序员,十分优秀!