我有一些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文件?
我正在java中编写一个测试工具,用于与ikev2协议相关的程序.作为其中的一部分,我需要能够计算ECDSA签名(特别是使用NIST P-256曲线).
RFC 4754描述了在IKEv2中使用ECDSA并有助于提供一组测试向量(包括我需要的p256曲线).
我正在尝试使用以下代码通过java的ECDSA签名实现运行ECDSA-256测试向量值(RFC中的第8.1节):
//"abc" for the input
byte[] input = { 0x61, 0x62, 0x63 };
//Ugly way of getting the ECParameterSpec for the P-256 curve by name as opposed to specifying all the parameters manually.
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");
ECGenParameterSpec kpgparams = new ECGenParameterSpec("secp256r1");
kpg.initialize(kpgparams);
ECParameterSpec params = ((ECPublicKey) kpg.generateKeyPair().getPublic()).getParams();
//Create the static private key W from the Test Vector
ECPrivateKeySpec static_privates = new ECPrivateKeySpec(new BigInteger("DC51D3866A15BACDE33D96F992FCA99DA7E6EF0934E7097559C27F1614C88A7F", 16), params);
KeyFactory kf = KeyFactory.getInstance("EC");
ECPrivateKey spriv = …Run Code Online (Sandbox Code Playgroud) 我正在使用以下示例在Node.js中进行签名+验证:https://github.com/nodejs/node-v0.x-archive/issues/6904.验证在Node.js中成功,但在WebCrypto中失败.同样,使用WebCrypto签名的消息无法在Node.js中进行验证.
这是我用来验证使用WebCrypto从Node.js脚本生成的签名的代码 - https://jsfiddle.net/aj49e8sj/.在Chrome 54.0.2840.27和Firefox 48.0.2中进行了测试
// From https://github.com/nodejs/node-v0.x-archive/issues/6904
var keys = {
priv: '-----BEGIN EC PRIVATE KEY-----\n' +
'MHcCAQEEIF+jnWY1D5kbVYDNvxxo/Y+ku2uJPDwS0r/VuPZQrjjVoAoGCCqGSM49\n' +
'AwEHoUQDQgAEurOxfSxmqIRYzJVagdZfMMSjRNNhB8i3mXyIMq704m2m52FdfKZ2\n' +
'pQhByd5eyj3lgZ7m7jbchtdgyOF8Io/1ng==\n' +
'-----END EC PRIVATE KEY-----\n',
pub: '-----BEGIN PUBLIC KEY-----\n' +
'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEurOxfSxmqIRYzJVagdZfMMSjRNNh\n' +
'B8i3mXyIMq704m2m52FdfKZ2pQhByd5eyj3lgZ7m7jbchtdgyOF8Io/1ng==\n' +
'-----END PUBLIC KEY-----\n'
};
var message = (new TextEncoder('UTF-8')).encode('hello');
// Algorithm used in Node.js script is ecdsa-with-SHA1, key generated with prime256v1
var algorithm = {
name: 'ECDSA',
namedCurve: 'P-256',
hash: {
name: 'SHA-1'
}
};
// Signature …Run Code Online (Sandbox Code Playgroud) 我需要将 OpenSSL 私钥加载到基于 C# 的应用程序中。
我用来生成密钥的命令是:
$ openssl ecparam -name prime256v1 -genkey -noout -out eckey.pem
$ openssl ec -in eckey.pem
read EC key
writing EC key
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIMiuwhV+yI0od5E5pSU6ZGuUcflskYD4urONi1g3G7EPoAoGCCqGSM49
AwEHoUQDQgAEe+C/M6u171u5CcL2SQKuFEb+OIEibjw1rx+S5LK4gNNePlDV/bqu
Ofjwc5JDqXA07shbfHNIPUn6Hum7qdiUKg==
-----END EC PRIVATE KEY-----
openssl pkcs8 -topk8 -nocrypt -in eckey.pem -out ec2.pem
cat ec2.pem
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgyK7CFX7IjSh3kTml
JTpka5Rx+WyRgPi6s42LWDcbsQ+hRANCAAR74L8zq7XvW7kJwvZJAq4URv44gSJu
PDWvH5LksriA014+UNX9uq45+PBzkkOpcDTuyFt8c0g9Sfoe6bup2JQq
-----END PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)
我正在使用的 C# 代码
string privKeyPKCS8 = @"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgyK7CFX7IjSh3kTmlJTpka5Rx+WyRgPi6s42LWDcbsQ+hRANCAAR74L8zq7XvW7kJwvZJAq4URv44gSJuPDWvH5LksriA014+UNX9uq45+PBzkkOpcDTuyFt8c0g9Sfoe6bup2JQq";
byte[] privKeyBytes8 = Convert.FromBase64String(privKeyPKCS8);//Encoding.UTF8.GetBytes(privKeyEcc);
var pubCNG = CngKey.Import(privKeyBytes, CngKeyBlobFormat.EccPrivateBlob);
Run Code Online (Sandbox Code Playgroud)
将基于 EC 的密钥加载到 CngKey 中的正确方法是什么?
编辑
Base 64 …
我正在尝试创建一个 C# 实现,通过他们的 HTTP/2 APNS 端点和 Docker 中的 .Net 核心向 Apple 发送推送。其中一部分需要将加密的 JWT 授权令牌与有效负载一起发送。使用 .Net 核心,我可以在 Windows 上运行时对令牌进行签名,但是在 Linux Docker 映像中运行时,它会提示加载密钥。
在 .net Core Docker Image 中运行时,我在加载密钥时遇到 platformnotsupported Exception。
public static string SignES256(string privateKey, string header, string payload)
{
// This is the failing Call
CngKey key = CngKey.Import(Convert.FromBase64String(privateKey), CngKeyBlobFormat.Pkcs8PrivateBlob);
using (ECDsaCng dsa = new ECDsaCng(key))
{
var unsignedJwtData =
System.Convert.ToBase64String(Encoding.UTF8.GetBytes(header)) + "." + System.Convert.ToBase64String(Encoding.UTF8.GetBytes(payload));
var unsignedJwtDataBytes = Encoding.UTF8.GetBytes(unsignedJwtData);
var signature =
dsa.SignData(unsignedJwtDataBytes, 0, unsignedJwtDataBytes.Length, HashAlgorithmName.SHA256 );
return unsignedJwtData + …Run Code Online (Sandbox Code Playgroud) 我有一个代表私钥的未加密 PKCS8 编码文件。它可以是这些私钥类型中的任何一种 - RSA、DSA 或 EC。我在 ASN1 解码器 ( https://lapo.it/asn1js/ ) 中查看了这些文件,我可以看到数据中的类型(RSA、DSA 或 EC)。
有没有办法将 PKC8 私钥数据读入正确的私钥 Java 对象,而无需在这样的代码中指定密钥类型 -
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(pkcs8key);
KeyFactory factory = KeyFactory.getInstance("RSA"); // Avoid "RSA" here?
PrivateKey privateKey = factory.generatePrivate(spec);
Run Code Online (Sandbox Code Playgroud)
有没有办法避免在 中指定算法KeyFactory.getInstance("RSA")?这不应该由 确定,PKCS8EncodedKeySpec因为它在 PKCS8 数据中可用?
示例未加密的 PKCS8 数据及其显示密钥类型的 ASN1 解码 -
动态搜索广告 -链接
EC -链接
RSA -链接
我正在尝试使用 PHP通过 ES256 签名的 JWT(根据他们在https://developer.apple.com/documentation/appstoreconnectapi 上的说明)对 Apple 的 AppStoreConnect API 进行身份验证。
发送我的请求总是会导致401 NOT_AUTHORIZED错误。
我已经验证了我的标题和声明的内容是正确的 - 我什至在网上找到了一个 Ruby 脚本来生成一个 ES256 签名的 JWT 并使用我的 Apple 提供的颁发者、密钥 ID、私钥,它运行良好 - Apple 接受令牌. 这告诉我我的凭据很好,但我在 php 中做错了。
除非我只是盯着这段代码看太久,否则 JWT 格式是正确的,base64 编码正确,并且不记名令牌在标头中设置正确。
为了排除请求发送的问题,我尝试了 GuzzleHTTP 和 CLI cURL - 都是 401。
这是相关的代码。您将看到该create方法正在对标头和声明进行编码、签署“有效负载”并连接所有 3 个。
public function create()
{
$header = $this->encode(
json_encode([
'kid' => 'my_key_id',
'alg' => 'ES256',
'typ' => 'JWT',
])
);
$claims = $this->encode(
json_encode([
'iss' => 'my_issuer_uuid',
'exp' => …Run Code Online (Sandbox Code Playgroud) 当集成 Sign in with Apple 时,您会在您的 Apple 开发者帐户中生成一个密钥。
这是一个名为AuthKey_3JMD5K6.p8和看起来像的文件
-----BEGIN PRIVATE KEY-----
MasdfjalskdasdflaASDFAadsflkjaADSFAewfljasdfljkasefasdflkjasdf
asdfljkasdfASDFASDFoiqretasdoiyjlfsbgREtaREGSDFBREtafsrgAREGfdsgaregR
LKJIOEWFNLasdflkawefjoiasdflk
-----END PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)
所以我做了一个var appleKey := MasdfjalskdasdflaASDFAadsflkjaADSFAewfljasdfljkasefasdflkjasdf asdfljkasdfASDFASDFoiqretasdoiyjlfsbgREtaREGSDFBREtafsrgAREGfdsgaregRLKJIOEWFNLasdflkawefjoiasdflk
我之前已经使用 HMAC-SHA 方法对 jwt 进行了签名,这相当简单,但我不知道如何使用 ECDSA 方法对 jwt 进行签名。
我以与 HMAC-SHA 方法相同的方式编写代码,但出现错误key is of invalid type
那么使用 golang 的 jwt 库如何使用 ECDSA 方法签署我的 jwt ?
我的代码
-----BEGIN PRIVATE KEY-----
MasdfjalskdasdflaASDFAadsflkjaADSFAewfljasdfljkasefasdflkjasdf
asdfljkasdfASDFASDFoiqretasdoiyjlfsbgREtaREGSDFBREtafsrgAREGfdsgaregR
LKJIOEWFNLasdflkawefjoiasdflk
-----END PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)
我现在知道这不是你的做法,而且比这更复杂一些,但是该怎么做呢?
我发现这篇文章告诉您如何手动执行此操作:
http://p.agnihotry.com/post/validating_sign_in_with_apple_authorization_code/
但我已经将 golang 的 jwt 库用于令牌的其他部分: https:
//godoc.org/github.com/dgrijalva/jwt-go
考虑以下使用 RSA 的代码...
例子:
byte[] raw = Encoding.Default.GetBytes("Hello, World!");
RSA key = RSA.Create();
for (int index = 0; index < 5; index++)
{
byte[] signed = key.SignData(raw, HashAlgorithmType.SHA256, RSASignaturePadding.Pkcs1);
string hashed = signed.ToSha256String();
Console.WriteLine(hashed);
}
Run Code Online (Sandbox Code Playgroud)
输出:
043a718774c572bd8a25adbeb1bfcd5c0256ae11cecf9f9c3f925d0e52beaf89 043a718774c572bd8a25adbeb1bfcd5c0256ae11cecf9f9c3f925d0e52beaf89 043a71877 4c572bd8a25adbeb1bfcd5c0256ae11cecf9f9c3f925d0e52beaf89 043a718774c572bd8a25adbeb1bfcd5c0256ae11cecf9f9c3f925d0e52beaf89 043a718774c572bd8a25 adbeb1bfcd5c0256ae11cecf9f9c3f925d0e52beaf89
现在考虑相同的代码,除了使用 ECDSA...
例子:
byte[] raw = Encoding.Default.GetBytes("Hello, World!");
ECDsa key = ECDsa.Create();
for (int index = 0; index < 5; index++)
{
byte[] signed = key.SignData(raw, HashAlgorithmType.SHA256);
string hashed = signed.ToSha256String();
Console.WriteLine(hashed);
}
Run Code Online (Sandbox Code Playgroud)
输出:
043a718774c572bd8a25adbeb1bfcd5c0256ae11cecf9f9c3f925d0e52beaf89 a31fe9656fc8d3a459e623dc8204e6d0268f8df56d734dac3ca3262edb5db883 a871c47a7 …
Let's Encrypt Certbot 默认密钥类型已更改为最新版本 2.0.0 的 ECDSA。如何指定生成RSA或ECDSA的密钥类型?