/// <summary> /// Validates server acceptance message /// </summary> /// <remark> /// Here the client verifies that the received message length is 80 /// bytes, then opens the encrypted box and verifies that the sent /// message is server's signature to the derived shared secrets. With /// this the handshake concludes. /// </remark> /// <exception cref="ArgumentException"> /// Thrown if the server's Accept <paramref name="msg"/> is not the /// correct size or the signature is not valid. /// </exception> /// <param name="msg"> /// The received message, encrypted server's signature. /// </param> public void VerifyAccept(byte[] msg) { if (msg.Length != 80) { throw new ArgumentException("Incorrect message size"); } var nonce = new byte[NONCE_SIZE]; nonce.Initialize(); // Concatenate the network key and derived secrets to obtain // the message key var key = CryptoHash.Sha256( Utils.Concat(_network_key, _shared_ab, _shared_aB, _shared_Ab) ); var opened_msg = SecretBox.Open(msg, nonce, key); // Compute the message that it is supposed to be signed with the // server's long term key var hashed = CryptoHash.Sha256(_shared_ab); var msg_to_verify = Utils.Concat( _network_key, detached_signature_A, _longterm_client_keypair.PublicKey, hashed ); if (!PublicKeyAuth.VerifyDetached(opened_msg, msg_to_verify, _longterm_server_pk)) { throw new ArgumentException("Invalid signature"); } }
public static void DecryptPacket(Socket socket, ServerState state, byte[] packet) { var messageId = BitConverter.ToInt32(new byte[2].Concat(packet.Take(2)).Reverse().ToArray(), 0); var payloadLength = BitConverter.ToInt32(new byte[1].Concat(packet.Skip(2).Take(3)).Reverse().ToArray(), 0); var unknown = BitConverter.ToInt32(new byte[2].Concat(packet.Skip(2).Skip(3).Take(2)).Reverse().ToArray(), 0); var cipherText = packet.Skip(2).Skip(3).Skip(2).ToArray(); byte[] plainText; if (messageId == 10100) { plainText = cipherText; } else if (messageId == 10101) { state.clientKey = cipherText.Take(32).ToArray(); var nonce = GenericHash.Hash(state.clientKey.Concat(state.serverKey.PublicKey).ToArray(), null, 24); cipherText = cipherText.Skip(32).ToArray(); plainText = PublicKeyBox.Open(cipherText, nonce, state.serverKey.PrivateKey, state.clientKey); state.sessionKey = plainText.Take(24).ToArray(); state.clientState.nonce = plainText.Skip(24).Take(24).ToArray(); plainText = plainText.Skip(24).Skip(24).ToArray(); } else { state.clientState.nonce = Utilities.Increment(Utilities.Increment(state.clientState.nonce)); plainText = SecretBox.Open(new byte[16].Concat(cipherText).ToArray(), state.clientState.nonce, state.sharedKey); } Console.WriteLine("[UCR] {0}" + Environment.NewLine + "{1}", PacketInfos.GetPacketName(messageId), Utilities.BinaryToHex(packet.Take(7).ToArray()) + Utilities.BinaryToHex(plainText)); ClientCrypto.EncryptPacket(state.clientState.socket, state.clientState, messageId, unknown, plainText); }
public void Decrypt() { try { if (this.m_vType == 10101) { byte[] array = this.m_vData; this.Client.CPublicKey = array.Take(32).ToArray <byte>(); this.Client.CSharedKey = this.Client.CPublicKey; this.Client.CRNonce = Client.GenerateSessionKey(); byte[] nonce = GenericHash.Hash(this.Client.CPublicKey.Concat(Key.Crypto.PublicKey).ToArray <byte>(), null, 24); array = array.Skip(32).ToArray <byte>(); byte[] source = PublicKeyBox.Open(array, nonce, Key.Crypto.PrivateKey, this.Client.CPublicKey); this.Client.CSessionKey = source.Take(24).ToArray <byte>(); this.Client.CSNonce = source.Skip(24).Take(24).ToArray <byte>(); this.SetData(source.Skip(24).Skip(24).ToArray <byte>()); } else { this.Client.CSNonce = Sodium.Utilities.Increment(Sodium.Utilities.Increment(this.Client.CSNonce)); this.SetData(SecretBox.Open(new byte[16].Concat(this.m_vData).ToArray <byte>(), this.Client.CSNonce, this.Client.CSharedKey)); } } catch (Exception) { this.Client.CState = 0; } }
public void SecretBox7() { byte[] k = new byte[SecretBox.KeySize]; byte[] n = new byte[SecretBox.NonceSize]; RandomNumberGenerator random = new RNGCryptoServiceProvider(); int mlen; for (mlen = 0; mlen < 1000; ++mlen) { byte[] m = new byte[mlen + SecretBox.ZeroSize]; byte[] c = new byte[mlen + SecretBox.ZeroSize]; byte[] m2 = new byte[mlen + SecretBox.ZeroSize]; random.GetBytes(k); random.GetBytes(n); random.GetBytes(m); Array.Clear(m, 0, SecretBox.ZeroSize); SecretBox secretBox = new SecretBox(k); secretBox.Box(c, m, n); secretBox.Open(m2, c, n); int i; for (i = 0; i < mlen + SecretBox.ZeroSize; ++i) { Assert.AreEqual(m2[i], m[i]); } } }
public static byte[] Decrypt(byte[] message, byte[] rxKey) { var nonce = message.Take(crypto_secretbox_NONCEBYTES).ToArray(); var cipher = message.Skip(crypto_secretbox_NONCEBYTES).ToArray(); return(SecretBox.Open(cipher, nonce, rxKey)); }
public void OpenSecretBoxBadNonce() { SecretBox.Open( Utilities.HexToBinary("00000000000000000000000000000000b58d3c3e5ae78770b7db54e29e3885138a2f1ddb738f2309d9b38164"), Encoding.UTF8.GetBytes("ABCDEFGHIJKLMNOPQRSTUVW"), Encoding.UTF8.GetBytes("12345678901234567890123456789012")); }
public void Decrypt() { try { if (m_vType == 10101) { byte[] cipherText = m_vData; Client.CPublicKey = cipherText.Take(32).ToArray(); Client.CSharedKey = Client.CPublicKey; Client.CRNonce = Client.GenerateSessionKey(); byte[] nonce = GenericHash.Hash(Client.CPublicKey.Concat(Key.Crypto.PublicKey).ToArray(), null, 24); cipherText = cipherText.Skip(32).ToArray(); var PlainText = PublicKeyBox.Open(cipherText, nonce, Key.Crypto.PrivateKey, Client.CPublicKey); Client.CSessionKey = PlainText.Take(24).ToArray(); Client.CSNonce = PlainText.Skip(24).Take(24).ToArray(); SetData(PlainText.Skip(24).Skip(24).ToArray()); } else { Client.CSNonce = Utilities.Increment(Utilities.Increment(Client.CSNonce)); SetData(SecretBox.Open(new byte[16].Concat(m_vData).ToArray(), Client.CSNonce, Client.CSharedKey)); } } catch (Exception ex) { Client.CState = 0; return; } }
public static void DecryptPacket(ServerState state, byte[] packet) { using (var reader = new Reader(packet)) { var ID = reader.ReadUInt16(); reader.Seek(3, SeekOrigin.Current); var Version = reader.ReadUInt16(); byte[] cipherText = reader.ReadAllBytes, plainText; var Name = Packet_Names.GetName(ID); switch (ID) { case 10100: { plainText = cipherText; break; } case 10101: { state.ClientKey = cipherText.Take(32).ToArray(); var nonce = GenericHash.Hash(state.ClientKey.Concat(state.ServerKey.PublicKey).ToArray(), null, 24); cipherText = cipherText.Skip(32).ToArray(); plainText = PublicKeyBox.Open(cipherText, nonce, state.ServerKey.PrivateKey, state.ClientKey); state.SessionKey = plainText.Take(24).ToArray(); state.ClientState.Nonce = plainText.Skip(24).Take(24).ToArray(); plainText = plainText.Skip(24).Skip(24).ToArray(); break; } default: { state.ClientState.Nonce = Utilities.Increment(Utilities.Increment(state.ClientState.Nonce)); plainText = SecretBox.Open(new byte[16].Concat(cipherText).ToArray(), state.ClientState.Nonce, state.SharedKey); break; } } ClientCrypto.EncryptPacket(state.ClientState, ID, Version, plainText); Console.WriteLine( $"[{DateTime.Now.ToLongTimeString()}, CLIENT, {ID}] {Resources.Definition.Decode(new Reader(plainText), ID)}"); Logger.Write(BitConverter.ToString(plainText).Replace("-", string.Empty), $"{ID}_{Name}", LogType.PACKET); } }
public async static Task <byte[]> ReadSecretMessage(Stream s, byte[] key, CancellationToken token = default) { var read = 0; byte[] header = new byte[4 + 24]; while (read < header.Length) { read += await s.ReadAsync(header, read, header.Length - read, token); } var length = BitConverter.ToUInt32(header, 0); byte[] nonce = header.Skip(4).ToArray(); if (length > MaxMessageLen) { throw new ArgumentOutOfRangeException($"Encrypted message specified a size of {length}, which is greater than the limit of {MaxMessageLen}"); } byte[] ciphertext = new byte[length]; read = 0; while (read < ciphertext.Length) { read += await s.ReadAsync(ciphertext, read, ciphertext.Length - read, token); } return(SecretBox.Open(ciphertext, nonce, key)); }
private static byte[] DecryptSecretSeed(byte[] seedBytes, byte[] keyHash) { byte[] nonceBytes = new byte[24]; byte[] cipherBytes = new byte[seedBytes.Length - nonceBytes.Length]; Array.Copy(seedBytes, 0, nonceBytes, 0, nonceBytes.Length); Array.Copy(seedBytes, nonceBytes.Length, cipherBytes, 0, cipherBytes.Length); return(SecretBox.Open(cipherBytes, nonceBytes, keyHash)); }
static string SecretboxDecryptionFromBase64(string keyBase64, string ciphertextReceivedBase64) { String[] parts = ciphertextReceivedBase64.Split(':'); byte[] nonce = Base64Decoding(parts[0]); byte[] ciphertext = Base64Decoding(parts[1]); var decrypted = SecretBox.Open(ciphertext, nonce, Base64Decoding(keyBase64)); return(System.Text.Encoding.UTF8.GetString(decrypted, 0, decrypted.Length)); }
/// <summary> /// Decrypts the Data into a byte[] /// </summary> /// <param name="locked">locked Data to be decrypted</param> public byte[] UnlockBytes(ILocked locked) { if (locked == null) { throw new ArgumentNullException(nameof(locked)); } return(SecretBox.Open(locked.Ciphertext, locked.Nonce.Bytes, key.Bytes)); }
public void OpenSecretBoxBadKey() { Assert.Throws <KeyOutOfRangeException>(() => { SecretBox.Open( Utilities.HexToBinary("00000000000000000000000000000000b58d3c3e5ae78770b7db54e29e3885138a2f1ddb738f2309d9b38164"), Encoding.UTF8.GetBytes("ABCDEFGHIJKLMNOPQRSTUVWX"), Encoding.UTF8.GetBytes("123456789012345678901234567890")); }); }
public void OpenSecretBox() { const string EXPECTED = "Adam Caudill"; var actual = Encoding.UTF8.GetString(SecretBox.Open( Utilities.HexToBinary("00000000000000000000000000000000b58d3c3e5ae78770b7db54e29e3885138a2f1ddb738f2309d9b38164"), Encoding.UTF8.GetBytes("ABCDEFGHIJKLMNOPQRSTUVWX"), Encoding.UTF8.GetBytes("12345678901234567890123456789012"))); Assert.AreEqual(EXPECTED, actual); }
public string Decrypt(string cipher, byte[] key) { byte[] cipherBytes = Utilities.HexToBinary(cipher); var nonce = cipherBytes.Take(24).ToArray(); var messageBytes = cipherBytes.Skip(24).ToArray(); var message = Utilities.BinaryToHex(messageBytes); var secret = SecretBox.Open(messageBytes, nonce, key); var secretMessage = Encoding.UTF8.GetString(secret); return(secretMessage); }
public void SecretBoxOpenWithGeneratedDataTest() { var key = SecretBox.GenerateKey(); var nonce = SecretBox.GenerateNonce(); String message = "Hello, World!"; byte[] plainText = System.Text.Encoding.UTF8.GetBytes(message); byte[] cipherText = SecretBox.Create(plainText, nonce, key); byte[] decrypted = SecretBox.Open(cipherText, nonce, key); Assert.AreEqual(plainText.ToString(), decrypted.ToString()); }
public static byte[] Decrypt(byte[] Payload, KeyPair keyPair) { ushort Id; int Length; ushort Version; using (Reader reader = new Reader(Payload)) { Id = reader.ReadUInt16(); Length = reader.ReadInt24(); Version = reader.ReadUInt16(); Payload = Payload.Skip(2).Skip(3).Skip(2).ToArray(); } if (!Form1.Config.UseRC4) { switch (Id) { case 20100: decryptedPayload = Payload; break; case 20103: decryptedPayload = Payload; break; case 20104: ClientConfig.ServerNonce = GenericHash.Hash(ClientConfig.SNonce.Concat(keyPair.PublicKey).Concat(Keys.ServerKey).ToArray(), null, 24); decryptedPayload = PublicKeyBox.Open(Payload, ClientConfig.ServerNonce, keyPair.PrivateKey, Keys.ServerKey); ClientConfig.RNonce = decryptedPayload.Take(24).ToArray(); ClientConfig.SharedKey = decryptedPayload.Skip(24).Take(32).ToArray(); decryptedPayload = decryptedPayload.Skip(24).Skip(32).ToArray(); break; default: ClientConfig.RNonce = Utilities.Increment(Utilities.Increment(ClientConfig.RNonce)); byte[] toDecrypt = new byte[16].Concat(Payload).ToArray(); decryptedPayload = SecretBox.Open(toDecrypt, ClientConfig.RNonce, ClientConfig.SharedKey); Logger.Write(Encoding.UTF8.GetString(decryptedPayload), "Decrypted OHD"); break; } } else if (Form1.Config.UseRC4) { decryptedPayload = RC4.Decrypt(Payload); } else { } return(decryptedPayload); }
/// <summary> /// Checks for <paramref name="msg"/> length and validity, extracting /// the client's long term public key upon success. /// </summary> /// <param name="msg">Client authenticate message</param> /// <exception cref="ArgumentException"> /// Thrown if the client Auth <paramref name="msg"/> fails to pass the /// checks. /// </exception> public void AcceptAuth(byte[] msg) { if (msg.Length != 112) { throw new ArgumentException("Incorrect secretbox length"); } // A nonce consisting of 24 zeros var nonce = new byte[NONCE_SIZE]; nonce.Initialize(); // Calculate the decryption key from the dervided keys var key = CryptoHash.Sha256( Utils.Concat(_network_key, _shared_ab, _shared_aB) ); var opened_msg = SecretBox.Open(msg, nonce, key); if (opened_msg.Length != 96) { throw new ArgumentException("Invalid size of opened message"); } // Extract the signature of the long term client's public key // signed with the derived secret var detached_signature = new byte[SIG_SIZE]; Buffer.BlockCopy(opened_msg, 0, detached_signature, 0, SIG_SIZE); // Extract the long term client's public key var lt_cli_pk = new byte[PUB_KEY_SIZE]; Buffer.BlockCopy(opened_msg, SIG_SIZE, lt_cli_pk, 0, PUB_KEY_SIZE); var shared_hashed = CryptoHash.Sha256(_shared_ab); // Concat network_key, server longterm pk and sha256 hashed shared_ab secret var to_verify = Utils.Concat( _network_key, _longterm_server_keypair.PublicKey, shared_hashed ); if (!PublicKeyAuth.VerifyDetached(detached_signature, to_verify, lt_cli_pk)) { throw new ArgumentException("Signature does not match"); } detached_signature_A = detached_signature; _longterm_client_pk = lt_cli_pk; this.DeriveAb(); }
public void Decrypt() { var Message = Encoding.ASCII.GetBytes("Hello World"); var Key = SodiumCore.GetRandomBytes(32); var Nonce = SodiumCore.GetRandomBytes(24); var CipherText = SecretBox.Create(Message, Nonce, Key); var PlainText = SecretBox.Open(CipherText, Nonce, Key); Assert.AreEqual(Encoding.ASCII.GetString(Message), Encoding.ASCII.GetString(PlainText)); }
/// <summary> /// MultiboxOpenBody /// </summary> /// <param name="cypherText"></param> /// <param name="length_and_key"></param> /// <returns></returns> public static byte[] MultiboxOpenBody(byte[] cypherText, byte[] length_and_key) { if (length_and_key == null) { return(null); } var key = SubArray(length_and_key, 1, length_and_key.Length - 1); var length = length_and_key[0]; var start = 24 + 32; var size = 32 + 1 + 16; var nonce = SubArray(cypherText, 0, 24); return(SecretBox.Open(SubArray(cypherText, start + length * size, cypherText.Length - (start + length * size)), nonce, key)); }
public void SecretBox8() { byte[] k = new byte[SecretBox.KeySize]; byte[] n = new byte[SecretBox.NonceSize]; RandomNumberGenerator cryptoRandom = new RNGCryptoServiceProvider(); Random random = new Random(); int mlen; for (mlen = 0; mlen < 1000; ++mlen) { byte[] m = new byte[mlen + SecretBox.ZeroSize]; byte[] c = new byte[mlen + SecretBox.ZeroSize]; byte[] m2 = new byte[mlen + SecretBox.ZeroSize]; cryptoRandom.GetBytes(k); cryptoRandom.GetBytes(n); cryptoRandom.GetBytes(m); Array.Clear(m, 0, SecretBox.ZeroSize); SecretBox secretBox = new SecretBox(k); secretBox.Box(c, m, n); int caught = 0; while (caught < 10) { c[random.Next(0, mlen + SecretBox.ZeroSize)] = (byte)(random.Next() % 255); try { secretBox.Open(m2, c, n); int i; for (i = 0; i < mlen + SecretBox.ZeroSize; ++i) { Assert.AreEqual(m2[i], m[i]); } } catch (SecurityException ex) { caught++; } } } }
public void SecretBoxOpenTest() { var key = "7IygDz/Hy8LC/wqXb6vsrpq7Vyn7mxCoh8nYOn5yVXc="; var nonce = "bUBIsnfvIv2Wo95SEkt4DIvBqZLGGBjV"; byte[] message = System.Text.Encoding.UTF8.GetBytes("Hello, World!"); String cipherText = "cZFTGV7SrPeSdX5Q6b30PBEm5Y2uby/W5BSrrfU="; byte[] cipherTextBytes = Convert.FromBase64String(cipherText); byte[] bitKey = Convert.FromBase64String(key); byte[] bitNonce = Convert.FromBase64String(nonce); byte[] plainText = SecretBox.Open(cipherTextBytes, bitNonce, bitKey); Assert.AreEqual(message.ToString(), plainText.ToString()); }
public static byte[] Decrypt(byte[] encrypted) { byte[] decrypted; ushort id; int length; ushort version; using (var reader = new Reader(encrypted)) { id = reader.ReadUInt16(); length = reader.ReadInt24(); version = reader.ReadUInt16(); } encrypted = encrypted.Skip(2).Skip(3).Skip(2).ToArray(); switch (id) { case 10100: decrypted = encrypted; break; case 10101: ServerConfig.clientPublicKey = encrypted.Take(32).ToArray(); encrypted = encrypted.Skip(32).ToArray(); ServerConfig.clientSharedKey = ServerConfig.clientPublicKey; ServerConfig.clientRNonce = Utils.GenerateRandomBytes(24); byte[] nonce = GenericHash.Hash(ServerConfig.clientPublicKey.Concat(Keys.ServerKey).ToArray(), null, 24); decrypted = PublicKeyBox.Open(encrypted, nonce, ServerConfig.privateKey, ServerConfig.clientPublicKey); ServerConfig.clientSessionKey = decrypted.Take(24).ToArray(); ServerConfig.clientSNonce = decrypted.Skip(24).Take(24).ToArray(); ServerConfig.clientSNonce = ServerConfig.clientSNonce; decrypted = decrypted.Skip(24).Skip(24).ToArray(); Console.WriteLine(BitConverter.ToString(ServerConfig.clientSNonce).Replace("-", "")); Console.WriteLine(BitConverter.ToString(ServerConfig.clientSessionKey).Replace("-", "")); Console.WriteLine(BitConverter.ToString(nonce).Replace("-", "")); Console.WriteLine(BitConverter.ToString(ServerConfig.clientPublicKey).Replace("-", "")); break; default: ServerConfig.clientSNonce = Utilities.Increment(Utilities.Increment(ServerConfig.clientSNonce)); decrypted = SecretBox.Open(new byte[16].Concat(encrypted).ToArray(), ServerConfig.clientSNonce, ServerConfig.clientSharedKey); break; } return(decrypted); }
public static void DecryptPacket(Socket socket, ServerState state, byte[] packet) { int messageId = BitConverter.ToInt32(new byte[2].Concat(packet.Take(2)).Reverse().ToArray(), 0); int payloadLength = BitConverter.ToInt32(new byte[1].Concat(packet.Skip(2).Take(3)).Reverse().ToArray(), 0); int unknown = BitConverter.ToInt32(new byte[2].Concat(packet.Skip(2).Skip(3).Take(2)).Reverse().ToArray(), 0); byte[] cipherText = packet.Skip(2).Skip(3).Skip(2).ToArray(); byte[] plainText; if (messageId == 10100) { plainText = cipherText; } else if (messageId == 10101) { state.clientKey = cipherText.Take(32).ToArray(); byte[] nonce = GenericHash.Hash(state.clientKey.Concat(state.serverKey.PublicKey).ToArray(), null, 24); cipherText = cipherText.Skip(32).ToArray(); plainText = PublicKeyBox.Open(cipherText, nonce, state.serverKey.PrivateKey, state.clientKey); state.sessionKey = plainText.Take(24).ToArray(); state.clientState.nonce = plainText.Skip(24).Take(24).ToArray(); plainText = plainText.Skip(24).Skip(24).ToArray(); } else { state.clientState.nonce = Utilities.Increment(Utilities.Increment(state.clientState.nonce)); plainText = SecretBox.Open(new byte[16].Concat(cipherText).ToArray(), state.clientState.nonce, state.sharedKey); } try { JObject decoded = state.decoder.decode(messageId, 0, plainText); var msg = new Message(messageId, "[C > S] " + decoded["name"], plainText, unknown, state, decoded["fields"].ToString()); MainWindow.Context.AddMessageToQueueLog(msg); } catch (Exception) { var msg = new Message(messageId, "[C > S] " + "Undefined", plainText, unknown, state, ""); MainWindow.Context.AddMessageToQueueLog(msg); } ClientCrypto.EncryptPacket(state.clientState.socket, state.clientState, messageId, unknown, plainText); }
public byte[] RecoverPrivateKey(string argon2mode, string walletPassword) { try { byte[] salt = Hex.Decode(Crypto.KdfParams.Salt); Argon2 arg = Utils.Crypto.GetArgon2FromType(argon2mode, walletPassword); //mpiva get from wallet not from config arg.DegreeOfParallelism = Crypto.KdfParams.Parallelism; //_config.Parallelism; arg.Iterations = Crypto.KdfParams.OpsLimit; //_config.OpsLimit; arg.MemorySize = Crypto.KdfParams.MemLimitKib; //_config.MemLimitKIB; arg.Salt = salt; byte[] rawHash = arg.GetBytes(32); // extract nonce byte[] nonce = Hex.Decode(Crypto.CipherParams.Nonce); // extract cipertext byte[] ciphertext = Hex.Decode(Crypto.CipherText); // recover private key byte[] decrypted = null; try { decrypted = SecretBox.Open(ciphertext, nonce, rawHash); } // ReSharper disable once EmptyGeneralCatchClause catch { } if (decrypted == null) { throw new AException("Error recovering privateKey: wrong password."); } return(decrypted); } catch (Exception e) { throw new AException("Error recovering privateKey: wrong password.", e); } }
/// <summary> /// Asynchronously reads a message from the stream. /// </summary> /// <returns>An array with the decrypted message</returns> /// <param name="msg">A stream with incoming messages</param> public async Task <byte[]> Unbox(Stream msg) { var enc_header = new byte[HEAD_LEN]; await msg.ReadAsync(enc_header, 0, HEAD_LEN); var header = SecretBox.Open(enc_header, nonce, key); var length_buf = header.Take(2).ToArray(); if (BitConverter.IsLittleEndian) { Array.Reverse(length_buf); } var length = BitConverter.ToUInt16(length_buf, 0); var boxed_body = new byte[length]; await msg.ReadAsync(boxed_body, 0, length); var to_unbox = Utils.Concat(header.Skip(2).ToArray(), boxed_body); return(SecretBox.Open(to_unbox, nonce, key)); }
public static void DecryptPacket(Socket socket, ServerState state, byte[] packet) { int messageId = BitConverter.ToInt32(new byte[2].Concat(packet.Take(2)).Reverse().ToArray(), 0); int payloadLength = BitConverter.ToInt32(new byte[1].Concat(packet.Skip(2).Take(3)).Reverse().ToArray(), 0); int unknown = BitConverter.ToInt32(new byte[2].Concat(packet.Skip(2).Skip(3).Take(2)).Reverse().ToArray(), 0); byte[] cipherText = packet.Skip(2).Skip(3).Skip(2).ToArray(); byte[] plainText; if (messageId == 10100) { plainText = cipherText; } else if (messageId == 10101) { state.clientKey = cipherText.Take(32).ToArray(); byte[] nonce = GenericHash.Hash(state.clientKey.Concat(state.serverKey.PublicKey).ToArray(), null, 24); cipherText = cipherText.Skip(32).ToArray(); plainText = PublicKeyBox.Open(cipherText, nonce, state.serverKey.PrivateKey, state.clientKey); state.sessionKey = plainText.Take(24).ToArray(); state.clientState.nonce = plainText.Skip(24).Take(24).ToArray(); plainText = plainText.Skip(24).Skip(24).ToArray(); } else { state.clientState.nonce = Utilities.Increment(Utilities.Increment(state.clientState.nonce)); plainText = SecretBox.Open(new byte[16].Concat(cipherText).ToArray(), state.clientState.nonce, state.sharedKey); } try { JObject decoded = state.decoder.decode(messageId, unknown, plainText); Console.WriteLine("{0}: {1}", decoded["name"], decoded["fields"]); } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine("{0} {1}", messageId, Utilities.BinaryToHex(BitConverter.GetBytes(messageId).Reverse().Skip(2).Concat(BitConverter.GetBytes(plainText.Length).Reverse().Skip(1)).Concat(BitConverter.GetBytes(unknown).Reverse().Skip(2)).Concat(plainText).ToArray())); } ClientCrypto.EncryptPacket(state.clientState.socket, state.clientState, messageId, unknown, plainText); }
public void LoadPrivateKey(SecureString password, bool save = true, string path = null) { if (string.IsNullOrEmpty(path)) { path = (Environment.OSVersion.Platform == PlatformID.Unix) ? Environment.GetEnvironmentVariable("HOME") : Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%"); path += "/.cryptchat/" + Base32.ToBase32String(GenericHash.Hash(Encoding.ASCII.GetBytes(Username), null, 16)) + "/.pem"; } if (!File.Exists(path)) { Console.WriteLine("Generating keypair"); using (KeyPair kp = Security.Boxes.Asymmetric.GenerateKeyPair()) { Console.WriteLine("Store PrivateKey as mem-locked Base64 string"); PrivateKey = Convert.ToBase64String(kp.PrivateKey); Console.WriteLine("Store PublicKey as Base64 string"); PublicKey = Convert.ToBase64String(kp.PublicKey); if (save) { SavePrivateKey(password); } } } else { var cipher_file = File.ReadAllBytes(path); PrivateKey = Convert.ToBase64String(SecretBox.Open(cipher_file, GenericHash.Hash(Encoding.ASCII.GetBytes(Id), null, 24), GenericHash.Hash(Encoding.ASCII.GetBytes(password), null, 32))); using (var kpair = PublicKeyBox.GenerateKeyPair(Convert.FromBase64String(PrivateKey.ToString()))) { PublicKey = Convert.ToBase64String(kpair.PublicKey); } } }
public static string Decrypt(string crypt, string secretKey, string nonce) { byte[] secret_bytes; byte[] nonce_bytes; byte[] crypt_bytes; if (Utils.IsBase64(nonce)) { nonce_bytes = Convert.FromBase64String(nonce); } else { throw new ArgumentException($"{nameof(nonce)} must be a Base64-encoded string"); } if (Utils.IsBase64(crypt)) { crypt_bytes = Convert.FromBase64String(crypt); } else { throw new ArgumentException($"{nameof(crypt)} must be a Base64-encoded string"); } if (!Utils.IsBase64(secretKey)) { secret_bytes = Encoding.ASCII.GetBytes(secretKey); } else { secret_bytes = Convert.FromBase64String(secretKey); } var plaintext = SecretBox.Open(crypt_bytes, nonce_bytes, secret_bytes); return(Encoding.UTF8.GetString(plaintext)); }
/// <summary> /// MultiboxOpenKey /// </summary> /// <param name="cypherText"></param> /// <param name="secretKey"></param> /// <param name="maxRecipients"></param> /// <returns>return null if secretKey is not valid</returns> public static byte[] MultiboxOpenKey(byte[] cypherText, byte[] secretKey, int maxRecipients = DEFAULT_MAX) { if (maxRecipients < 1 || maxRecipients > 255) { throw new ArgumentOutOfRangeException("max recipients must be between 1 and 255."); } var nonce = SubArray(cypherText, 0, 24); var onetime_pk = SubArray(cypherText, 24, 32); var my_key = ScalarMult.Mult(secretKey, onetime_pk); var start = 24 + 32; var size = 32 + 1 + 16; for (var i = 0; i <= maxRecipients; i++) { var s = start + size * i; if (s + size > (cypherText.Length - 16)) { return(null); } try { var length_and_key = SecretBox.Open(SubArray(cypherText, s, size), nonce, my_key); if (length_and_key != null) { return(length_and_key); } } catch (System.Security.Cryptography.CryptographicException) { } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(ex.Message); } } return(null); }