问题描述
我正在使用自签名证书 ECDH_secP384r1
来签名令牌.这是我创建证书的PowerShell:
I'm using self signed certificate ECDH_secP384r1
for signing token.Here is the PowerShell that I create the certificate:
$Cert = New-SelfSignedCertificate -certstorelocation cert:\localmachine\my -dnsname $Certname -NotAfter $ExpireDate -KeyAlgorithm ECDH_secP384r1
现在,在我的.net核心应用程序中,我首先加载证书:
Now in my .net core application first I load the certificate:
private readonly string _certificateSubjectName;
public X509Certificate2 GetSigningCertificate()
{
using (var store = new X509Store(StoreLocation.LocalMachine))
{
store.Open(OpenFlags.ReadOnly);
var certificates = store.Certificates.Find(X509FindType.FindBySubjectName, _certificateSubjectName, false);
return certificates[0];
}
}
现在有了证书,我在创建SigningCredentials时出错:我试图按照这种方式遵循
Now by having the certificate I got an error in creating SigningCredentials:I tried to follow this way
public string GetSignedToken(IEnumerable<Claim> claims)
{
var signingCertificate = GetSigningCertificate();
byte[] certBytes = signingCertificate.Export(X509ContentType.Pkcs12);
var privateECDsa = LoadPrivateKey(certBytes);
var signingCredentials = new SigningCredentials(new ECDsaSecurityKey(privateECDsa), SecurityAlgorithms.EcdsaSha384);
var token = new JwtSecurityToken(
issuer: _issuer,
audience: _audience,
claims: claims,
expires: DateTime.Now.AddMinutes(_expiryMinutes),
signingCredentials: signingCredentials);
var securityTokenHandler = new JwtSecurityTokenHandler();
var rawJwtToken = securityTokenHandler.WriteToken(token);
return rawJwtToken ;
}
private static ECDsa LoadPrivateKey(byte[] key)
{
var privKeyInt = new Org.BouncyCastle.Math.BigInteger(+1, key);
var parameters = SecNamedCurves.GetByName("secP384r1");
var ecPoint = parameters.G.Multiply(privKeyInt);
var privKeyX = ecPoint.Normalize().XCoord.ToBigInteger().ToByteArrayUnsigned();
var privKeyY = ecPoint.Normalize().YCoord.ToBigInteger().ToByteArrayUnsigned();
var curve = ECCurve.NamedCurves.nistP384;
var d = privKeyInt.ToByteArrayUnsigned();
var q = new ECPoint
{
X = privKeyX,
Y = privKeyY
};
var eCParameters = new ECParameters
{
Curve = curve,
D = d,
Q = q
};
var eCDsa = ECDsa.Create(eCParameters); //In this line I got an exception
return eCDsa;
}
但是我在ECDsa.Create中遇到了一个例外:
But I got an exception in ECDsa.Create:
The specified key parameters are not valid. Q.X and Q.Y are required fields. Q.X, Q.Y must be the same length. If D is specified it must be the same length as Q.X and Q.Y for named curves or the same length as Order for explicit curves.
更新:
我还尝试了这种固定尺寸的方法:
var d = FixSize(privKeyInt.ToByteArrayUnsigned(), privKeyX.Length);
但是在这种情况下 input [0]!= 0
我遇到了一个异常,我的 input [0]
不是0另外 input.Length
为1250,预期大小为48
but in this condition input[0] != 0
I got an exception, my input[0]
is not 0Also the input.Length
is 1250 and expected size is 48
我错过了什么?有什么想法.
What I missed? any idea please.
推荐答案
好吧,经过一番搜索,我发现一个简单的解决方案,我在这里将其作为答案:
Ok, after some search I found an easy solution, I put it as an answer here:
using System.Security.Cryptography.X509Certificates;
public string GetSignedToken(IEnumerable<Claim> claims)
{
var signingCertificate = GetSigningCertificate();
var securityKey = new ECDsaSecurityKey(signingCertificate.GetECDsaPrivateKey());
var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.EcdsaSha384);
var token = new JwtSecurityToken(
issuer: _issuer,
audience: _audience,
claims: claims,
expires: DateTime.Now.AddMinutes(_expiryMinutes),
signingCredentials: signingCredentials);
var securityTokenHandler = new JwtSecurityTokenHandler();
var rawJwtToken = securityTokenHandler.WriteToken(token);
return rawJwtToken;
}
并进行验证:
using System.Security.Cryptography.X509Certificates;
public TokenValidationParameters GetTokenValidationParameters()
{
var signingCertificate = GetSigningCertificate();
var securityKey = new ECDsaSecurityKey(signingCertificate.GetECDsaPublicKey());
var validationParameters = new TokenValidationParameters()
{
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = securityKey,
ValidateIssuer = true,
ValidIssuer = _issuer,
ValidateAudience = true,
ValidAudience = _audience
};
return validationParameters;
}
这篇关于带有ECC加密证书的签名令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!