2016-04-16 13 views
0

Ich habe Probleme beim Öffnen einer Nacl SecretBox (in Java mit der TweetNaclFast-Bibliothek erzeugt) in C# mit der Bibliothek libsodium-net. Ich kann es auch nicht anders herum tun (öffne eine libsodium-net-generierte Box mit TweetNaclFast)."SecretBox" von TweetNacl (Java) kann nicht mit "Libsodium-net" (C#) geöffnet werden

Im folgenden Beispiel i eine SecretBox erstellen werden TweetNaclFast (Java) und versuchen, es zu öffnen mit libsodium-net (C#)

die SecretBox (Java) Erstellen

String secretMessage = "Hello Stack overflow!"; 
    byte[] messageBytes = secretMessage.getBytes("UTF-8"); 
    byte[] keyBytes = secureRandomGenerator(); //returns 32 random bytes (256 bits) 
    byte[] nonceBytes = TweetNaclFast.makeSecretBoxNonce(); 

    byte[] boxBytes = new TweetNaclFast.SecretBox(keyBytes).box(messageBytes,nonceBytes); 

    System.out.println("Base64 box -> "+Base64.encodeBase64String(boxBytes)); 
    System.out.println("Base64 key -> "+Base64.encodeBase64String(keyBytes)); 
    System.out.println("Base64 nonce -> "+Base64.encodeBase64String(nonceBytes)); 

Creation Ausgabe

Base64 box -> iNEpgwFIo6nyaLNgMpSWqwTQ9Z5y/y+BUXszXVFZ2gP2A3XJ0Q== 
Base64 key -> FKpCo/AhRRUjdQIpzMbZSnnzfBx1e/Ni9VZyNWYEB8E= 
Base64 nonce -> 2qngWbMLFVNiPTFqTVO9nsraB8ACIrwV 

die SecretBox Öffnungs (C#)

string box = "iNEpgwFIo6nyaLNgMpSWqwTQ9Z5y/y+BUXszXVFZ2gP2A3XJ0Q=="; 
string key = "FKpCo/AhRRUjdQIpzMbZSnnzfBx1e/Ni9VZyNWYEB8E="; 
string nonce = "2qngWbMLFVNiPTFqTVO9nsraB8ACIrwV"; 


     try 
     { 
      byte[] message = Sodium.SecretBox.Open(
      Convert.FromBase64String(box), 
      Convert.FromBase64String(nonce), 
      Convert.FromBase64String(key)); 

      Console.WriteLine(Encoding.UTF8.GetString(message)); 
     } 
     catch (CryptographicException e) 
     { 
      Console.WriteLine(e.Message); 
      Console.WriteLine(e.StackTrace); 
     } 

öffnen Ausgang

Failed to open SecretBox 
    at Sodium.SecretBox.Open(Byte[] cipherText, Byte[] nonce, Byte[] key) 

Jede Idee, über das, was ich falsch tun könnte?


EDIT

Ich denke, das Problem mit einer der Bibliotheken (libsodium-net höchstwahrscheinlich). Wenn ich eine SecretBox mit den gleichen Variablen erstelle ich eine andere Box bekommen ...

a Secret Box mit TweetNaclFast Erstellen

String message = "Hello Stack overflow!"; 
String key = "uCEgauAQDWGDkcclGe1rNV6V77xtizuemhgxzM5nqO4="; 
String nonce = "+RTDstWX1Wps5/btQzSMHWBqHU9s6iqq"; 

SecretBox box = new SecretBox(Base64.decodeBase64(key)); 
byte[] cipherText = box.box(message.getBytes("UTF-8"), Base64.decodeBase64(nonce)); 

RÜCKKEHR: yDCt/kOLFUWPZpV3deVNUZaH0ZHLVmj9Nvm8QlbVKPe1a/INDw ==

Erstellen einer geheimen Box mit libnodium-net

string message = "Hello Stack overflow!"; 
string key = "uCEgauAQDWGDkcclGe1rNV6V77xtizuemhgxzM5nqO4="; 
string nonce = "+RTDstWX1Wps5/btQzSMHWBqHU9s6iqq"; 

byte[] box = Sodium.SecretBox.Create(Encoding.UTF8.GetBytes(message), 
              Convert.FromBase64String(nonce), 
              Convert.FromBase64String(key)); 

Console.WriteLine(Convert.ToBase64String(box)); 

RÜCKKEHR: AAAAAAAAAAAAAAAAAAAAAMgwrf5DixVFj2aVd3XlTVGWh9GRy1Zo/Tb5vEJW1Sj3tWvyDQ8 =

Antwort

1

Sodium.SecretBox.Create verwendet die ursprüngliche NaCl crypto_box() API, die vor der Nachricht und dem Chiffretext eine zusätzliche Auffüllung erfordert.

Diese API ist ein wenig verwirrend und ist nur in C selten nützlich. Sogar in C schreiben Leute, die es benutzen, Wrapper, um das Padding voranzustellen oder loszuwerden.

Die Konstruktionen box und , die von den meisten APIs bereitgestellt werden, erfordern keine zusätzliche Auffüllung. Der Chiffretext wird direkt ohne 16 zusätzliche Bytes vorher zurückgegeben. Die Nachricht kann direkt gegeben werden, ohne dass 16 Nul-Bytes vorangestellt werden.

TweetNaclFast erfordert keine Auffüllung, aber libsodium-net tut das anscheinend.

Die zusätzlichen 16 Bytes vor dem Chiffretext, den Sie mit libsodium-net beobachten, enthalten keine nützlichen Informationen. Es ist nur ein Haufen Nullen. Sie können sie sicher entfernen und später hinzufügen, wenn Sie aufrufen.

Beachten Sie, dass im Gegensatz zu Sodium.SecretBox, Sodium.PublicKeyBox keine Auffüllung erforderlich ist.

+0

Das ist genau das, was ich gefunden habe. Danke für die Erklärung :) – loveMeansNothing

+1

Das ist eigentlich [eine Inkonsistenz in libsodium-net] (https://github.com/adamcaudill/libsodium-net/issues/133). Kompatible Funktionen [wurden hinzugefügt] (https://github.com/bitbeans/libsodium-net/commit/0d718a4c4d2d1f148a081864496fff7620245956). –

+0

Sie rocken @Frank Denis – loveMeansNothing

0

ich die Dokumentation (RTFM) gelesen haben sollte ... Anscheinend libsodium-net auf Beginn des verschlüsselten Text eine 16-Byte-Authentifizierung Tag fügt (https://bitbeans.gitbooks.io/libsodium-net/content/secret-key_cryptography/authenticated_encryption.html). Wenn ich die ersten 16 Bytes entferne, bekomme ich die gleiche Ausgabe wie die TweetNaclFast SecretBox.

string message = "Hello Stack overflow!"; 
string key = "uCEgauAQDWGDkcclGe1rNV6V77xtizuemhgxzM5nqO4="; 
string nonce = "+RTDstWX1Wps5/btQzSMHWBqHU9s6iqq"; 

byte[] box = Sodium.SecretBox.Create(Encoding.UTF8.GetBytes(message), 
              Convert.FromBase64String(nonce), 
              Convert.FromBase64String(key)); 

byte[] boxWithoutAuthenticationTag = new byte[box.Length - 16]; 
Array.Copy(box, 16, boxWithoutAuthenticationTag, 0, box.Length - 16); 
Console.WriteLine(Convert.ToBase64String(boxWithoutAuthenticationTag)); 

jetzt zurück: yDCt/kOLFUWPZpV3deVNUZaH0ZHLVmj9Nvm8QlbVKPe1a/INDw ==


zu öffnen (entschlüsseln) die erste geheime Box Beispiel den folgenden Code:

string box = "iNEpgwFIo6nyaLNgMpSWqwTQ9Z5y/y+BUXszXVFZ2gP2A3XJ0Q=="; 
string key = "FKpCo/AhRRUjdQIpzMbZSnnzfBx1e/Ni9VZyNWYEB8E="; 
string nonce = "2qngWbMLFVNiPTFqTVO9nsraB8ACIrwV"; 

try 
{ 
    //Libsodium-net SecretBox.Open() requires a 16 byte authentication tag at the start of the ciphertext 
    //TweetNaclFast boxing method does not append a 16 byte authentication tag anywhere 
    //Thus, we need to add a 16 byte authentication tag at the start of ciphertext encripted by TweetNaclFast 
    byte[] authenticationTag = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; //Zeroed 16 Bytes Authentication Tag 
    byte[] tweetNaclFastCiphertextBytes = Convert.FromBase64String(box); 
    byte[] libsodiumNetLikeCiphertext = new byte[tweetNaclFastCiphertextBytes.Length + authenticationTag.Length]; 
    Array.Copy(authenticationTag, libsodiumNetLikeCiphertext, authenticationTag.Length); 
    Array.Copy(tweetNaclFastCiphertextBytes, 0, libsodiumNetLikeCiphertext, authenticationTag.Length, tweetNaclFastCiphertextBytes.Length); 
    byte[] nonceBytes = Convert.FromBase64String(nonce); 
    byte[] keyBytes = Convert.FromBase64String(key); 

    Console.WriteLine(Encoding.UTF8.GetString(Sodium.SecretBox.Open(libsodiumNetLikeCiphertext, nonceBytes, keyBytes))); 
} 
catch (CryptographicException e) 
{ 
    Console.WriteLine(e.Message); 
    Console.WriteLine(e.StackTrace); 
} 

Es sollte Jetzt zurück Hallo Stack Überlauf!