Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.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
C# System.Security.Cryptography.CryptographyException:不支持请求的操作。windows server 2012_C#_Encryption_Cryptography_Public Key Encryption_Cng - Fatal编程技术网

C# System.Security.Cryptography.CryptographyException:不支持请求的操作。windows server 2012

C# System.Security.Cryptography.CryptographyException:不支持请求的操作。windows server 2012,c#,encryption,cryptography,public-key-encryption,cng,C#,Encryption,Cryptography,Public Key Encryption,Cng,我已经厌倦了为调用APN生成jwt令牌。这是我的密码: var header = new Dictionary<string, object>() { { "kid" , keyID } }; var payload = new Dictionary<string, object>() { { "iss", teamID }, { "iat", DateTimeOffset.Now.T

我已经厌倦了为调用APN生成jwt令牌。这是我的密码:

    var header = new Dictionary<string, object>()
    {
        { "kid" , keyID }
    };
    var payload = new Dictionary<string, object>()
    {
        { "iss", teamID },
        { "iat", DateTimeOffset.Now.ToUnixTimeSeconds().ToString() }
    };

    var privateKey = GetApnsPrivateKey(authKeyPath);
    var token = JWT.Encode(payload, privateKey, JwsAlgorithm.ES256, header);
public static CngKey GetApnsPrivateKey(string authKeyPath)
{
    using (var reader = new StreamReader(new FileStream(authKeyPath, FileMode.Open, FileAccess.Read, FileShare.Read)))
    {
        var ecPrivateKeyParameters = (ECPrivateKeyParameters)new PemReader(reader).ReadObject();
        var x = ecPrivateKeyParameters.Parameters.G.AffineXCoord.GetEncoded();
        var y = ecPrivateKeyParameters.Parameters.G.AffineYCoord.GetEncoded();
        var d = ecPrivateKeyParameters.D.ToByteArrayUnsigned();
        return EccKey.New(x, y, d);
在论坛上搜索了一下后,我发现它是因为CNG密钥存储提供商:
现在我想知道有什么方法可以解决这个问题吗?

异常的来源是jose jwt中的System.Security.Cryptography库,所以要避免它。 由于BouncyCastle库已在此处使用,请将其用于签名。 另外,我使用Newtonsoft.Json.JsonConvert(..)

公共字符串GetApnsToken(字符串authKeyPath,
字典负载,
字典标题)
{
ECPrivateKeyParameters ECPrivateKeyParameters;
使用(var reader=new StreamReader(新文件流(authKeyPath,FileMode.Open,FileAccess.Read,FileShare.Read)))
{
ecPrivateKeyParameters=(ecPrivateKeyParameters)新PemReader(reader.ReadObject();
}
byte[]headerBytes=Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header));
byte[]payloadBytes=Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(有效负载));
byte[]bytesToSign=Encoding.UTF8.GetBytes(ConcatTokenPartsWithEncoding(headerBytes,payloadBytes));
var signer=new-DsaDigestSigner(new-ECDsaSigner(),new-Sha256Digest());
signer.Init(true,ecPrivateKeyParameters);
BlockUpdate(bytesToSign,0,bytesToSign.Length);
byte[]signBytes=signer.GenerateSignature();
返回编码后的ConcatokenParts(headerBytes、payloadBytes、signBytes);
}
公共静态字符串concatokenpartswithencoding(参数字节[][]parts)
{
var builder=新的StringBuilder();
foreach(var零件中的零件)
{
//为Url编码base64
var base64Str=Convert.ToBase64String(部分);
base64Str=base64Str.Split('=')[0];//删除任何尾随的'='
base64Str=base64Str.Replace('+','-');
base64Str=base64Str.Replace(“/”,“"”);
builder.Append(base64Str).Append(“.”);
}
builder.Remove(builder.Length-1,1);
返回builder.ToString();
}

多亏了Natalya的帖子。我可以这样解决问题:

        var dateTime = DateTimeOffset.Now;
        var privateKeyAsBytes = Convert.FromBase64String(authKey);
        var privateKey = CngKey.Import(privateKeyAsBytes, CngKeyBlobFormat.Pkcs8PrivateBlob);
        var header = new Dictionary<string, object>() { { "kid", keyID } };
        var payload = new Dictionary<string, object>() { { "iss", teamID }, { "iat", dateTime.ToUnixTimeSeconds().ToString() } };
        var token = JWT.Encode(payload, privateKey, JwsAlgorithm.ES256, header);
var dateTime=DateTimeOffset.Now;
var privateKeyAsBytes=Convert.FromBase64String(authKey);
var privateKey=CngKey.Import(privateKeyAsBytes,CngKeyBlobFormat.Pkcs8PrivateBlob);
var header=newdictionary(){{“kid”,keyID};
var payload=newdictionary(){{“iss”,teamID},{“iat”,dateTime.ToUnixTimeSeconds().ToString()};
var token=JWT.Encode(有效载荷、私钥、JwsAlgorithm.ES256、报头);

EccKey.New
不是NetFx方法,那么它来自哪里/它的实现是什么?您好亲爱的@bartonjs。新的是加密库方法。下面是完整路径的方法:Security.Cryptography.EccKey.New(x,y,d);嗨,本例中的authKey是什么?我有与您相同的代码,但不确定如何更改为您在此处显示的代码
public string GetApnsToken(string authKeyPath,  
Dictionary<string, object> payload, 
Dictionary<string, object> header)
{
    ECPrivateKeyParameters ecPrivateKeyParameters;
    using (var reader = new StreamReader(new FileStream(authKeyPath, FileMode.Open, FileAccess.Read, FileShare.Read)))
    {
       ecPrivateKeyParameters = (ECPrivateKeyParameters)new PemReader(reader).ReadObject();
     }
     byte[] headerBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header));
     byte[] payloadBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload));
     byte[] bytesToSign = Encoding.UTF8.GetBytes(ConcatTokenPartsWithEncoding(headerBytes, payloadBytes));

   var signer = new DsaDigestSigner(new ECDsaSigner(), new Sha256Digest());
   signer.Init(true, ecPrivateKeyParameters);
   signer.BlockUpdate(bytesToSign, 0, bytesToSign.Length);
   byte[] signBytes = signer.GenerateSignature();

   return ConcatTokenPartsWithEncoding(headerBytes, payloadBytes, signBytes);

}

public static string ConcatTokenPartsWithEncoding(params byte[][] parts)
{
var builder = new StringBuilder();
foreach (var part in parts)
{
 //encode base64 for Url
 var base64Str = Convert.ToBase64String(part);
 base64Str = base64Str.Split('=')[0]; // Remove any trailing '='s
 base64Str = base64Str.Replace('+', '-'); 
 base64Str = base64Str.Replace('/', '_');
 builder.Append(base64Str).Append(".");
}
builder.Remove(builder.Length - 1, 1); 
return builder.ToString();
}
        var dateTime = DateTimeOffset.Now;
        var privateKeyAsBytes = Convert.FromBase64String(authKey);
        var privateKey = CngKey.Import(privateKeyAsBytes, CngKeyBlobFormat.Pkcs8PrivateBlob);
        var header = new Dictionary<string, object>() { { "kid", keyID } };
        var payload = new Dictionary<string, object>() { { "iss", teamID }, { "iat", dateTime.ToUnixTimeSeconds().ToString() } };
        var token = JWT.Encode(payload, privateKey, JwsAlgorithm.ES256, header);