2016-02-25 4 views
16

私は、Firefoxに存在する新しいPush APIと統合するプロジェクトに取り組んでおり、W3C標準として開発中です。ECDiffieHellmanP256での派生キー

この部分は、データを暗号化しています。 NETのBASE64に変換するときに、サーバは、この例(var key = subscription.getKey('p256dh');を使用してJSに生成される)デフィーヘルマンP256曲線

を受け取る

BOAiqZO6ucAzDlZKKhF1aLjNpU8 + R2Pfsz4bQzNpV145D + agNxvLqyu5Q2tLalK2w31RpoDHE8Sipo0m2jiX4WA =

ありますしかし、私は派生したマテリアルを生成する問題に遭遇しました。

var key1 = Convert.FromBase64String("<stringFromAbove>").ToList() // You can criticize my .toList inefficiencies later 

// .NET doesn't like the key without these prefixes. See here 
// http://stackoverflow.com/questions/24251336/import-a-public-key-from-somewhere-else-to-cngkey 
// I know the bytes don't match that post, but that is because the key type is different between their example and mine. 
var keyType = new byte[] { 0x45, 0x43, 0x4B, 0x31 }; 
var keyLength = new byte[] { 0x20, 0x00, 0x00, 0x00 }; 
key1.RemoveAt(0); 
key1 = keyType.Concat(keyLength).Concat(key1).ToList(); 

ECDiffieHellmanCng a = new ECDiffieHellmanCng(); 
a.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash; 
// If I set this as CngAlgorithm.Sha256 it works, but that's not what Firefox gives me. 
a.HashAlgorithm = CngAlgorithm.ECDiffieHellmanP256; 
a.KeySize = 256; // It complains if I don't add this since keys are different lengths. 

// Now time to actually import the key 
CngKey k = CngKey.Import(key1.ToArray(), CngKeyBlobFormat.EccPublicBlob); // Works successfully 
byte[] derivedMaterial = a.DeriveKeyMaterial(k); // Exception Here 

System.Security.Cryptography.CryptographicException:要求された操作はサポートされていません。

正しく理解していないこと(または、より悲しい側で、正しく実装されていないものは何か?)代替案として

、誰かが私はを通じて作業を継続するために必要な方法をあまりにも動作すると思います.NETへのポートこのNode JS libraryをする(私はそれが届くの少しだと思う)

更新
説明できる場合問題の残りの部分とではないが、暗号化により、最大保有ので、私は.NET側のさらなる発展を可能にするためにNode.jsのラッパーを使用すること。ノードコードは単にローカル公開鍵とSharedシークレットを生成し、それらの値を私に返します。私はまだノードラッパーなしでこれを動作させる必要があります。

このテストでは、残りのコード(ここには含まれていません)が動作することを確認できます。したがって、上記のコードに問題があることは間違いありません(HashAlgorithmが​​

+0

どのOSとフレームワークのバージョンで作業していますか? –

+0

Windowsで実行しています。 .NET Framework 4.6 –

+0

あなたはこれを見ましたか?http://stackoverflow.com/questions/31330363/does-ecdiffiehellmancng-in-net-have-a-key-derivation-function-that-implements-n –

答えて

5

このソリューションは、Windows 10の64ビットに取り組んで確認された。 Windows 8.1 64ビットで動作していない確認し、他のプラットフォーム上でテストしていないです。

問題はECDiffieHellmanP256がハッシュではないということですアルゴリズムではなく、ハッシュキー導出関数を使用するように指定しています。KeyDerivationFunctionECDiffieHellmanKeyDerivationFunction.Tlsに設定する必要があり、あなたがKDFのための種子やラベルを指定する必要があります。私はa.Labelプロパティにナンセンス値を設定し

var key1 = Convert.FromBase64String("BOAiqZO6ucAzDlZKKhF1aLjNpU8+R2Pfsz4bQzNpV145D+agNxvLqyu5Q2tLalK2w31RpoDHE8Sipo0m2jiX4WA=").ToList(); 
var keyType = new byte[] { 0x45, 0x43, 0x4B, 0x31 }; 
var keyLength = new byte[] { 0x20, 0x00, 0x00, 0x00 }; 
key1.RemoveAt(0); 
key1 = keyType.Concat(keyLength).Concat(key1).ToList(); 

ECDiffieHellmanCng a = new ECDiffieHellmanCng(); 
a.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Tls; 

byte[] label = new byte[32]; 
string labelStr = "The purpose"; 
Encoding.ASCII.GetBytes(labelStr, 0, labelStr.Length, label, 0); 
a.Label = label; 

byte[] seed = new byte[32]; 
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); 
rng.GetBytes(seed); 
a.Seed = seed; 

a.HashAlgorithm = CngAlgorithm.ECDiffieHellmanP256; 
a.KeySize = 256; 

CngKey k = CngKey.Import(key1.ToArray(), CngKeyBlobFormat.EccPublicBlob); 
byte[] derivedMaterial = a.DeriveKeyMaterial(k); 

注:

あなたの固定コードは次のようになります。 - バイナリ文字列として符号化された派生鍵材料、目的を識別する文字列

レーベル:

NIST SP 800-108 publicationのようにラベルを定義します。

あなたの特定の状況で目的がどのように設定されるべきかわかりません。誰かがこの文字列が何であるべきかをよく理解しているなら、コメントを残してください。

この関数を繰り返し呼び出す場合は、おそらくRNGCryptoServiceProviderの永続的なコピーを保存しておいてください。

comment by Simon Mourierのおかげで、私は正しい軌道に乗りました。

+0

あなたのコードは私に非常に有益な例外を与えます: 'パラメータが間違っています。 ' 前回私はこの問題を" KeyType "と" KeyLength "プロパティ(それを修正したものを追加する)を、私が' import'と呼んだときに取得するときです。今それはDeriveKeyMaterialコールで起こっています –

+0

@DanDrewsそれは奇妙です、それは.NET 4.6で私のためにうまく動作します。あなたが言及したこととは別に、あなたの最初の 'key1'が有効でないときにその例外を得ることができます。私の例の文字列を一時的にハードコーディングすることで、そうでないことを確認してください(私はあなたの例から取りました)。 –

+0

ちょうどあなたのコードの直接コピー/ペーストで新しいプロジェクトを試して、フレームワークを.NETに設定してください。4.6このマシンでは、Windows 8.1を実行しています。 –