2016-02-25 9 views
16

ich an einem Projekt arbeite mit den neuen Push API zu integrieren, die in Firefox existiert und als W3C-Standard entwickelt.Derive Key mit ECDiffieHellmanP256

Ein Teil davon ist, um die Daten zu verschlüsseln. (Unter Verwendung von var key = subscription.getKey('p256dh'); generiert in JS)

Ein Beispiel dafür wird der Server eine Diffie Hellman P256-Kurve erhalten, wenn zu einer .NET Base64 umgewandelt ist

BOAiqZO6ucAzDlZKKhF1aLjNpU8 + R2Pfsz4bQzNpV145D + agNxvLqyu5Q2tLalK2w31RpoDHE8Sipo0m2jiX4WA =

Allerdings stieß ich auf Probleme beim Generieren des abgeleiteten Materials.

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: Der angeforderte Vorgang wird nicht unterstützt.

Was verstehe ich nicht richtig (oder auf der eher traurigen Seite, was nicht (oder überhaupt) in Windows/.NET implementiert ist)?

Als Alternative könnte, wenn jemand erklären, wie man Port diese Node JS library dass auf .NET funktionieren würde (ich glaube, das ist ein bisschen eine Reichweite)

aktualisieren
ich durch die Arbeit zu halten benötigt der Rest des Problems und nicht durch die Verschlüsselung gehalten werden, so dass ich verwendet, um einen Node.JS Wrapper für die weitere Entwicklung auf der .NET-Seite zu ermöglichen. Der Knotencode generiert einfach den lokalen öffentlichen Schlüssel und das Shared Secret und gibt diese Werte an mich zurück. Ich brauche das immer noch ohne den Node-Wrapper.

Aufgrund dieses Tests kann ich bestätigen, dass der Rest des Codes (hier nicht enthalten) funktioniert, so dass das Problem definitiv im obigen Code liegt (und meine Unfähigkeit, das abgeleitete Schlüsselmaterial zu generieren, wenn der HashAlgorithm als CngAlgorithm.ECDiffieHellmanP256 angegeben ist

+0

An welcher OS- und Framework-Version arbeiten Sie? –

+0

Unter Windows ausgeführt. .NET Framework 4.6 –

+0

Haben Sie Folgendes gesehen: http://stackoverflow.com/questions/31330363/does-ecdiffiehellmancng-in-net-have-a-key-derivation-funktion-that-implements-n –

Antwort

5

Diese Lösung wird nur bestätigt, arbeitet an 10 Windows 64-Bit. Es ist unter Windows 8.1 64-Bit nicht bestätigt zu arbeiten, und auf anderen Plattformen nicht getestet ist.

Das Problem ist, dass ECDiffieHellmanP256 kein Hash Algorithmus, aber Sie geben an, eine Hash-Schlüsselableitungsfunktion zu verwenden. Ihre KeyDerivationFunction sollte ECDiffieHellmanKeyDerivationFunction.Tls eingestellt werden, und Sie müssen die Samen und die Bezeichnung für die KDF angeben.

Ihre festen Code sieht wie folgt aus:

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); 

Bitte beachte, dass ich einen Unsinn Wert auf die a.Label Eigenschaft festgelegt.

Die NIST SP 800-108 publication definiert das Etikett als:

Etikett - Ein String, der den Zweck, für den abgeleiteten Schlüsselmaterial identifiziert, das als binäre Zeichenkette codiert wird.

Ich bin nicht sicher, was der Zweck sollte in Ihrem spezifischen Kontext festgelegt werden. Wenn jemand besser versteht, was diese Zeichenfolge sein soll, hinterlasse bitte einen Kommentar.

Beachten Sie auch, dass wenn Sie diese Funktion wiederholt aufrufen, sollten Sie wahrscheinlich eine persistente Kopie der RNGCryptoServiceProvider behalten und diese verwenden.

Dank einer die mich auf die richtige Spur gebracht hat.

+0

Ihr Code gibt mir die sehr hilfreiche Ausnahme: 'Der Parameter ist falsch.' Das letzte Mal hatte ich dieses Problem hatte es mit dem" KeyType "und" KeyLength "Eigenschaften (Hinzufügen von denen behoben), wenn ich" Import "genannt, ist, wenn ich es bekommen würde.Jetzt passiert es auf dem DeriveKeyMaterial Anruf –

+0

@DanDrews Das ist seltsam, es funktioniert gut für mich auf .NET 4.6. Abgesehen von dem, was Sie erwähnt haben, können Sie diese Ausnahme erhalten, wenn Ihre anfängliche 'Schlüssel1' nicht gültig ist. Stellen Sie sicher, dass dies nicht der Fall ist, indem Sie die Zeichenfolge in meinem Beispiel (die ich Ihrem Beispiel entnommen habe) vorübergehend fest codieren. –

+0

In einem neuen Projekt mit einem direkten Kopieren/Einfügen Ihres Codes versucht, Framework auf .NET zu setzen. 4.6 Auf diesem Rechner läuft Windows 8.1, was machst du? –