2017-05-15 13 views
0

Docker에서 .Net 코어가있는 HTTP/2 APNS 끝점을 통해 Apple에 푸시를 보내려면 C# 구현을 만들려고합니다. 이 중 일부는 페이로드와 함께 암호화 된 JWT 권한 부여 토큰을 보내야합니다. .Net 코어를 사용하면 Windows에서 실행할 때 토큰에 서명 할 수 있지만 Linux Docker 이미지에서 실행할 때 키로드에 대한 팁이 있습니다.ECDsa Linux의 닷넷 코어

.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 + "." + System.Convert.ToBase64String(signature); 
     } 
    } 

Linux의 .Net Core에서 어떻게하면됩니까?

감사합니다.

답변

1

ECDsaCng은 Windows CNG를 사용하는 ECDSA 구현입니다. Windows에만 해당되므로 Linux에서는 지원되지 않습니다.

크로스 플랫폼 방법이 물론

using (ECDsa ecdsa = ECDsa.Create()) 
{ 
    ecdsa.ImportParameters(Pkcs8ToParameters(privateKey)); 

    // the stuff in your current using 
} 

것 할, ECParameters에 PKCS # 8 세계에서 가장 쉬운 일이 아니다. 그러나 우리는 그것을 줄 수 있습니다. another answer에는 RSA 용 PKCS # 8 빌드에 대한 분석이 있습니다.

은의이 덩어리를 보자 : 그것은 끝의 비트 문자열은 "공개 키"입니다

30 /* SEQUENCE */ 
    81 87 (payload is 0x87 bytes) 

    02 /* INTEGER */ 01 (1 byte) 00 // Integer: 0. // validate this 

    30 /* SEQUENCE */ 13 (0x13 bytes) 

     06 /* OBJECT IDENTIFIER */ 07 (7 bytes) 
     2A8648CE3D0201 (1.2.840.10045.2.1/ecPublicKey) // validate this 

     06 /* OBJECT IDENTIFIER */ 08 (8 bytes) 
     2A8648CE3D030107 (1.2.840.10045.3.1.7/secp256r1) // save this, curveName 

    04 /* OCTET STREAM (byte[]) */ 6D (0x6D bytes) 
     // Since the constructed (0x20) bit isn't set in the tag normally we stop here, 
     // but we know from the ecPublicKey context that this is also DER data. 

     30 /* SEQUENCE */ 6B (0x6B bytes) 

     02 /* Integer */ 01 (1 byte) 01 // Integer: 1. // validate this. 

     04 /* OCTET STREAM (byte[]) */ 20 (0x20 bytes/256 bits) 
      70A12C2DB16845ED56FF68CFC21A472B3F04D7D6851BF6349F2D7D5B3452B38A // save this: D 

     A1 /* CONSTRUCTED CONTEXT SPECIFIC 1 */ 44 (0x44 bytes) 

      03 /* BIT STRING (byte[] if the first byte is 0x00) */ 66 (0x66 bytes) 

       00 // Oh, good, it's a normal byte[]. Validate this. 

       // Formatting will become apparent. Save this. 
       04 
       8101ECE47464A6EAD70CF69A6E2BD3D88691A3262D22CBA4F7635EAFF26680A8 
       D8A12BA61D599235F67D9CB4D58F1783D3CA43E78F0A5ABAA624079936C0C3A9 

처럼 분해

308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B02 
0101042070A12C2DB16845ED56FF68CFC21A472B3F04D7D6851BF6349F2D7D5B 
3452B38AA144034200048101ECE47464A6EAD70CF69A6E2BD3D88691A3262D22 
CBA4F7635EAFF26680A8D8A12BA61D599235F67D9CB4D58F1783D3CA43E78F0A 
5ABAA624079936C0C3A9 

. 04으로 시작하기 때문에 (보통 보낸 사람이 화를 내 지 않는 한) "압축되지 않은 지점"을 의미합니다. 즉 왼쪽에있는 첫 번째 절반은 X 좌표이고 나머지는 Y 좌표입니다. 따라서이 구조에서 당신은

string curveOid; 

// You can decode the OID, or special case it. 
switch (curveName) 
{ 
    case "2A8648CE3D030107": 
     // secp256r1 
     curveOid = "1.2.840.10045.3.1.7"; 
     break; 
    case "2B81040022" 
     // secp384r1 
     curveOid = "1.3.132.0.34"; 
     break; 
    case "2B81040023": 
     // secp521r1 
     curveOid = "1.3.132.0.35"; 
     break; 
    default: 
     throw new InvalidOperationException(); 
} 

return new ECParameters 
{ 
    Curve = ECCurve.CreateFromValid(curveOid), 

    // We saved this. 
    D = d, 

    Q = new ECPoint 
    { 
     X = x, 
     Y = y 
    }, 
} 

이 키는 섹션 D.1 Suite B Implementer’s Guide to FIPS 186-3 (ECDSA)의 (NIST P-256/secp256r1)에 사용되는 일이 같은 것을 얻을 수 있습니다.

EC 키 형식은 INTEGER 값 (패딩 바이트가 필요할 수 있음)이 부족하기 때문에 지원하려는 각 키 크기에 대해 수동 추출기를 만들 수 있습니다. 또는 DER의 실시간 읽기 경로를 사용할 수 있습니다. 또는 개인 키를 응용 프로그램에보다 친숙한 형식으로 직렬화 할 수 있습니다.