/// <summary> /// Takes a 'plaintext' Buffer of the message you want to encrypt,<para /> /// and an array of recipient public keys.<para /> /// Returns a message that is encrypted to all recipients<para /> /// and openable by them with 'PrivateBox.MultiboxOpen'.<para /> /// The 'recipients' must be between 1 and 7 items long. /// </summary> /// <param name="msg"></param> /// <param name="recipients"></param> /// <param name="maxRecipients"></param> /// <returns></returns> /// <exception cref="ArgumentOutOfRangeException"></exception> public static byte[] Multibox(byte[] msg, byte[][] recipients, int maxRecipients = DEFAULT_MAX) { if (maxRecipients < 1 || maxRecipients > 255) { throw new ArgumentOutOfRangeException("max recipients must be between 1 and 255."); } if (recipients.Length > maxRecipients) { throw new ArgumentOutOfRangeException("max recipients is:" + maxRecipients + " found:" + recipients.Length); } var nonce = RandomBytes(24); var key = RandomBytes(32); var onetime = PublicKeyBox.GenerateKeyPair(); var length_and_key = new List <byte>(); length_and_key.Add((byte)recipients.Length); length_and_key.AddRange(key); var res = new List <byte>(); res.AddRange(nonce); res.AddRange(onetime.PublicKey); foreach (var rec in recipients) { res.AddRange(SecretBox.Create(length_and_key.ToArray(), nonce, ScalarMult.Mult(onetime.PrivateKey, rec))); } res.AddRange(SecretBox.Create(msg, nonce, key)); return(res.ToArray()); }
public void SavePrivateKey(SecureString password, string path = null) { Console.WriteLine("Set path if needed"); 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)); } Console.WriteLine("Create directory"); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } path += "/.pem"; Console.WriteLine("Lock PrivateKey with password"); var temp = SecretBox.Create(Convert.FromBase64String(PrivateKey), GenericHash.Hash(Encoding.ASCII.GetBytes(Id), null, 24), GenericHash.Hash(Encoding.ASCII.GetBytes(password), null, 32)); var temp_key = Convert.ToBase64String(temp); Console.WriteLine("Save password-locked PrivateKey"); if (!string.IsNullOrEmpty(temp_key)) { File.WriteAllBytes(path, Convert.FromBase64String(temp_key)); } }
static string SecretboxEncryptionToBase64(string keyBase64, string plaintext) { byte[] nonce = GenerateRandomNonce(); byte[] data = System.Text.Encoding.UTF8.GetBytes(plaintext); byte[] ciphertext = SecretBox.Create(plaintext, nonce, Base64Decoding(keyBase64)); return(Base64Encoding(nonce) + ":" + Base64Encoding(ciphertext)); }
public void Encrypt(byte[] plainText) { try { if (this.GetMessageType() == 20103) { byte[] nonce = GenericHash.Hash(this.Client.CSNonce.Concat(this.Client.CPublicKey).Concat(Key.Crypto.PublicKey).ToArray <byte>(), null, 24); plainText = this.Client.CRNonce.Concat(this.Client.CSharedKey).Concat(plainText).ToArray <byte>(); this.SetData(PublicKeyBox.Create(plainText, nonce, Key.Crypto.PrivateKey, this.Client.CPublicKey)); } else if (this.GetMessageType() == 20104) { byte[] nonce2 = GenericHash.Hash(this.Client.CSNonce.Concat(this.Client.CPublicKey).Concat(Key.Crypto.PublicKey).ToArray <byte>(), null, 24); plainText = this.Client.CRNonce.Concat(this.Client.CSharedKey).Concat(plainText).ToArray <byte>(); this.SetData(PublicKeyBox.Create(plainText, nonce2, Key.Crypto.PrivateKey, this.Client.CPublicKey)); this.Client.CState = 2; } else { this.Client.CRNonce = Sodium.Utilities.Increment(Sodium.Utilities.Increment(this.Client.CRNonce)); this.SetData(SecretBox.Create(plainText, this.Client.CRNonce, this.Client.CSharedKey).Skip(16).ToArray <byte>()); } } catch (Exception) { this.Client.CState = 0; } }
/// <summary> /// Encrypts the file name. /// </summary> /// <param name="fileName">The file name.</param> /// <param name="fileNameLength">The length it will be filled up.</param> public void ProtectFileName(string fileName, int fileNameLength) { //fill up the filename to 256 bytes byte[] paddedFileName = Helper.Utils.StringToPaddedByteArray(fileName, fileNameLength); //encrypt the file name in the header this.Filename = SecretBox.Create(paddedFileName, this.FilenameNonce, this.UnencryptedEphemeralKey); }
public static void EncryptPacket(Socket socket, ServerState state, int messageId, int unknown, byte[] plainText) { byte[] cipherText; if (messageId == 20100) { cipherText = plainText; } else if (messageId == 20104) { var nonce = GenericHash.Hash( state.clientState.nonce.Concat(state.clientKey).Concat(state.serverKey.PublicKey).ToArray(), null, 24); plainText = state.nonce.Concat(state.sharedKey).Concat(plainText).ToArray(); cipherText = PublicKeyBox.Create(plainText, nonce, state.serverKey.PrivateKey, state.clientKey); } else { cipherText = SecretBox.Create(plainText, state.nonce, state.sharedKey).Skip(16).ToArray(); } var packet = BitConverter.GetBytes(messageId) .Reverse() .Skip(2) .Concat(BitConverter.GetBytes(cipherText.Length).Reverse().Skip(1)) .Concat(BitConverter.GetBytes(unknown).Reverse().Skip(2)) .Concat(cipherText) .ToArray(); socket.BeginSend(packet, 0, packet.Length, 0, SendCallback, state); }
/// <summary> /// Crafts the client Authenticate message /// </summary> /// <remark> /// Consists of a signature of the network identifier, the server's /// long term public key and a sha 256 of the derived secret ab, /// concatenated with the client's long term public key. All /// encrypted using the network identifier and the derived secrets /// ab and aB. /// /// This sets the object's <see cref="detached_signature_A"/> /// </remark> /// <returns> /// The client Authenticate message /// </returns> public byte[] Authenticate() { var hash_ab = CryptoHash.Sha256(this._shared_ab); // Concatenate the network identifier, the server's public key and // the hash of the derived secret. var to_sign = Utils.Concat( _network_key, _longterm_server_pk, hash_ab ); // Sign the first portion of the message and save it in the object // state for later use in the server accept verification. detached_signature_A = PublicKeyAuth.SignDetached( to_sign, _longterm_client_keypair.PrivateKey ); // Create the plaintext message var plaintext = Utils.Concat( detached_signature_A, _longterm_client_keypair.PublicKey ); // Create the key from the network key and the shared secrets var box_key = Utils.Concat( _network_key, _shared_ab, _shared_aB ); // A nonce consisting of 24 zeros var nonce = new byte[NONCE_SIZE]; nonce.Initialize(); var msg = SecretBox.Create(plaintext, nonce, CryptoHash.Sha256(box_key)); return(msg); }
public static void EncryptPacket(Socket _Socket, ServerState _State, int _PacketID, int unknown, byte[] plainText) { byte[] cipherText; if (_PacketID == 20100) { cipherText = plainText; } else if (_PacketID == 20103) { byte[] nonce = GenericHash.Hash(_State.clientState.nonce.Concat(_State.clientKey).Concat(_State.serverKey.PublicKey).ToArray(), null, 24); plainText = _State.nonce.Concat(_State.sharedKey).Concat(plainText).ToArray(); cipherText = PublicKeyBox.Create(plainText, nonce, _State.serverKey.PrivateKey, _State.clientKey); } else if (_PacketID == 20104) { byte[] nonce = GenericHash.Hash(_State.clientState.nonce.Concat(_State.clientKey).Concat(_State.serverKey.PublicKey).ToArray(), null, 24); plainText = _State.nonce.Concat(_State.sharedKey).Concat(plainText).ToArray(); cipherText = PublicKeyBox.Create(plainText, nonce, _State.serverKey.PrivateKey, _State.clientKey); } else { cipherText = SecretBox.Create(plainText, _State.nonce, _State.sharedKey).Skip(16).ToArray(); } byte[] packet = BitConverter.GetBytes(_PacketID).Reverse().Skip(2).Concat(BitConverter.GetBytes(cipherText.Length).Reverse().Skip(1)).Concat(BitConverter.GetBytes(unknown).Reverse().Skip(2)).Concat(cipherText).ToArray(); _Socket.BeginSend(packet, 0, packet.Length, 0, SendCallback, _State); }
public void CreateSecretBoxBadNonce() { SecretBox.Create( Encoding.UTF8.GetBytes("Adam Caudill"), Encoding.UTF8.GetBytes("ABCDEFGHIJKLMNOPQRSTUVW"), Encoding.UTF8.GetBytes("12345678901234567890123456789012")); }
public void Encrypt(byte[] plainText) { try { if (GetMessageType() == 20103) { byte[] nonce = GenericHash.Hash(Client.CSNonce.Concat(Client.CPublicKey).Concat(Key.Crypto.PublicKey).ToArray(), null, 24); plainText = Client.CRNonce.Concat(Client.CSharedKey).Concat(plainText).ToArray(); SetData(PublicKeyBox.Create(plainText, nonce, Key.Crypto.PrivateKey, Client.CPublicKey)); } else if (GetMessageType() == 20104) { byte[] nonce = GenericHash.Hash(Client.CSNonce.Concat(Client.CPublicKey).Concat(Key.Crypto.PublicKey).ToArray(), null, 24); plainText = Client.CRNonce.Concat(Client.CSharedKey).Concat(plainText).ToArray(); SetData(PublicKeyBox.Create(plainText, nonce, Key.Crypto.PrivateKey, Client.CPublicKey)); Client.CState = 2; } else { Client.CRNonce = Utilities.Increment(Utilities.Increment(Client.CRNonce)); SetData(SecretBox.Create(plainText, Client.CRNonce, Client.CSharedKey).Skip(16).ToArray()); } } catch (Exception ex) { Client.CState = 0; } }
/// <summary> /// Computes the message that accepts the handshake. /// </summary> /// <remark> /// Here the server computes a signature of the network key, the /// signature of the long term client's public key and a sha 256 of /// the shared ab secret. This is signed with the server's long term /// private key. /// /// This signature is encrypted using a sha 256 of the network key /// and all of the derived secrets. /// </remark> /// <returns> /// A byte array of length 80 consisting of the message. /// </returns> public byte[] Accept() { var detached_signature = PublicKeyAuth.SignDetached( Utils.Concat( _network_key, detached_signature_A, _longterm_client_pk, CryptoHash.Sha256(_shared_ab) ), _longterm_server_keypair.PrivateKey ); // A nonce consisting of 24 zeros var nonce = new byte[NONCE_SIZE]; nonce.Initialize(); var key = CryptoHash.Sha256( Utils.Concat(_network_key, _shared_ab, _shared_aB, _shared_Ab) ); var msg = SecretBox.Create(detached_signature, nonce, key); return(msg); }
public ConnectPacketData GetConnectPacket() { var connectPacketData = new ConnectPacketData { AddressType = _connection.AddressType, DestPort = _connection.DestPort, RouteCount = (uint)_connection.ReturnRoutes.Length, ReturnRoutes = // TODO }; if (_connection.AddressType == DestAddressType.DomainName) { connectPacketData.DestDomainName = _connection.DestDomainName; } else { connectPacketData.DestIpAddress = _connection.DestIpAddress; } var bytesToEncrypt = new byte[PacketContent.MaxSendDataLen + 27]; var buffer = new WriteBuffer(bytesToEncrypt, 0); buffer.Write(_connection.UserId); buffer.Write(_connection.ConnectionId); buffer.Write(_connection.NextSequenceId); buffer.Write((byte)PacketDataType.Connect); buffer.Write(connectPacketData); var paddingLength = bytesToEncrypt.Length - buffer.TotalWritten; buffer.Write(new byte[paddingLength]); var route = GenerateRoute(_possibleNodes); var encrypted = SecretBox.Create(bytesToEncrypt, OneNonce, route.Nodes[2].SymmetricKey); var destIdAndDataLen = new byte[10]; buffer.Buffer = destIdAndDataLen; buffer.Write((ulong)0); buffer.Write((ushort)(encrypted.Length - 16)); var innerPacketBytes = new byte[bytesToEncrypt.Length + 67]; buffer.Buffer = innerPacketBytes; buffer.Write(route.Nodes[2].Node.Id); buffer.Write(route.Nodes[2].EphemeralPublicKey); buffer.Write((byte)(route.Nodes[2].SymmetricKey[31] & 1)); buffer.Write(StreamEncryption.EncryptChaCha20(destIdAndDataLen, ZeroNonce, route.Nodes[2].SymmetricKey)); buffer.Write(encrypted); encrypted = SecretBox.Create(encrypted, OneNonce, route.Nodes[2].SymmetricKey); var destId = new byte[8]; buffer.Buffer = destId; buffer.Write(route.Nodes[1].Node.Id); }
/// <summary> /// Sets the footer checksum. /// </summary> /// <param name="ephemeralKey">A 32 byte key.</param> /// <param name="footerChecksumLength">The length of the checksum.</param> public void SetFooterChecksum(byte[] ephemeralKey, int footerChecksumLength) { //protect the ChunkCount this.ChunkCount = SecretBox.Create(this.ChunkCount, this.FooterNonceCount, ephemeralKey); //protect the OverallChunkLength this.OverallChunkLength = SecretBox.Create(this.OverallChunkLength, this.FooterNonceLength, ephemeralKey); //generate and set the Footerchecksum this.FooterChecksum = Sodium.GenericHash.Hash(ArrayHelpers.ConcatArrays(this.ChunkCount, this.OverallChunkLength), ephemeralKey, footerChecksumLength); }
private static byte[] EncryptSecretSeed(byte[] seedBytes, byte[] keyHash) { byte[] nonceBytes = SecretBox.GenerateNonce(); byte[] cipherText = SecretBox.Create(seedBytes, nonceBytes, keyHash); byte[] encryptedSeed = new byte[cipherText.Length + nonceBytes.Length]; Array.Copy(nonceBytes, 0, encryptedSeed, 0, nonceBytes.Length); Array.Copy(cipherText, 0, encryptedSeed, nonceBytes.Length, cipherText.Length); return(encryptedSeed); }
/// <summary> /// Encrypts the file name. /// </summary> /// <param name="fileName">The file name.</param> /// <param name="fileNameLength">The length it will be filled up.</param> public void ProtectFileName(string fileName, int fileNameLength) { //fill up the filename to 256 bytes var paddedFileName = Utils.StringToPaddedByteArray(fileName, fileNameLength); //encrypt the file name in the header Filename = SecretBox.Create(paddedFileName, FilenameNonce, Utils.GetEphemeralEncryptionKey(UnencryptedEphemeralKey)); }
/// <summary> /// Encrypts the file name. /// </summary> /// <param name="fileName">The file name.</param> /// <param name="fileNameLength">The length it will be filled up.</param> /// <exception cref="OverflowException"></exception> /// <exception cref="ArgumentOutOfRangeException"></exception> /// <exception cref="ArgumentException"></exception> /// <exception cref="ArgumentNullException"></exception> public void ProtectFileName(string fileName, int fileNameLength) { //fill up the filename to 256 bytes var paddedFileName = Utils.AddPkcs7Padding(Encoding.UTF8.GetBytes(fileName), fileNameLength); //encrypt the file name in the header Filename = SecretBox.Create(paddedFileName, FilenameNonce, Utils.GetEphemeralEncryptionKey(UnencryptedEphemeralKey)); }
public string EncryptString(string message, byte[] key) { var nonce = SecretBox.GenerateNonce(); var secretMessage = SecretBox.Create(message, nonce, key); byte[] rv = new byte[nonce.Length + secretMessage.Length]; System.Buffer.BlockCopy(nonce, 0, rv, 0, nonce.Length); System.Buffer.BlockCopy(secretMessage, 0, rv, nonce.Length, secretMessage.Length); return(Utilities.BinaryToHex(rv)); }
public void CreateSecretBoxBadNonce() { Assert.Throws <NonceOutOfRangeException>(() => { SecretBox.Create( Encoding.UTF8.GetBytes("Adam Caudill"), Encoding.UTF8.GetBytes("ABCDEFGHIJKLMNOPQRSTUVW"), Encoding.UTF8.GetBytes("12345678901234567890123456789012")); }); }
public void CreateSecretBox() { var expected = Utilities.HexToBinary("00000000000000000000000000000000b58d3c3e5ae78770b7db54e29e3885138a2f1ddb738f2309d9b38164"); var actual = SecretBox.Create( Encoding.UTF8.GetBytes("Adam Caudill"), Encoding.UTF8.GetBytes("ABCDEFGHIJKLMNOPQRSTUVWX"), Encoding.UTF8.GetBytes("12345678901234567890123456789012")); CollectionAssert.AreEqual(expected, actual); }
/// <summary> /// Encrypts the Data (with Authentication) /// /// Primitive: XSalsa20 wiht Poly1305 MAC (libsodium crypto_secretbox) /// </summary> /// <param name="data">Data to be encrypted</param> /// <example> /// <code> /// var TEST_STRING = "eine kuh macht muh, viele kühe machen mühe" /// // Create a new Symmertic Key /// var key = new Key(); /// // Create a locker with this key /// var locker = new SecretLocker(key); /// var bytes = Utils.Secure.Encode(TEST_STRING); /// // Encrypt the bytes /// var ciphertext = locker.Lock(bytes); /// // Decrypt the Text /// var plaintext = locker.UnlockBytes(ciphertext); /// // Clear Keys /// locker.Clear(); /// </code> /// </example> public ILocked Lock(byte[] data) { if (data == null || data?.Length == 0) { throw new ArgumentNullException(nameof(data)); } var nonce = SecretBox.GenerateNonce(); var locked = SecretBox.Create(data, nonce, key.Bytes); return(new Locked(locked, new Nonce(nonce))); }
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()); }
/// <summary> /// Validates the footer checksum. /// </summary> /// <param name="chunkCount">Number of chunks in the file.</param> /// <param name="chunkOverallLength">Length of all chunks in the file.</param> /// <param name="ephemeralKey">A 32 byte key.</param> /// <param name="footerChecksumLength">The length of the checksum.</param> /// <exception cref="BadFileFooterException"></exception> public void ValidateFooterChecksum(byte[] chunkCount, byte[] chunkOverallLength, byte[] ephemeralKey, int footerChecksumLength) { byte[] footerChecksum = Sodium.GenericHash.Hash( ArrayHelpers.ConcatArrays(SecretBox.Create(chunkCount, this.FooterNonceCount, ephemeralKey), SecretBox.Create(chunkOverallLength, this.FooterNonceLength, ephemeralKey)), ephemeralKey, footerChecksumLength); //check the file footer if (!footerChecksum.SequenceEqual(this.FooterChecksum)) { throw new BadFileFooterException("Malformed file footer: file could be damaged or manipulated!"); } }
public static Keystore Generate(Configuration cfg, RawKeyPair rawKeyPair, string walletPassword, string walletName) { // create derived key with Argon2 byte[] salt = Utils.Crypto.GenerateSalt(cfg.DefaultSaltLength); Argon2 arg = Utils.Crypto.GetArgon2FromType(cfg.Argon2Mode, walletPassword); arg.DegreeOfParallelism = cfg.Parallelism; arg.Iterations = cfg.OpsLimit; arg.MemorySize = cfg.MemLimitKIB; arg.Salt = salt; byte[] rawHash = arg.GetBytes(32); // chain public and private key byte arrays byte[] privateAndPublicKey = rawKeyPair.ConcatenatedPrivateKey; // encrypt the key arrays with nonce and derived key byte[] nonce = SecretBox.GenerateNonce(); byte[] ciphertext = SecretBox.Create(privateAndPublicKey, nonce, rawHash); // generate walletName if not given if (walletName == null || walletName.Trim().Length == 0) { walletName = "generated wallet file - " + DateTime.Now; } // generate the domain object for keystore Keystore wallet = new Keystore { PublicKey = rawKeyPair.GetPublicKey(), Id = Guid.NewGuid().ToString().Replace("-", ""), Name = walletName, Version = cfg.Version, Crypto = new Crypto { SecretType = cfg.SecretType, SymmetricAlgorithm = cfg.SymmetricAlgorithm, CipherText = Hex.ToHexString(ciphertext), Kdf = cfg.Argon2Mode, CipherParams = new CipherParams { Nonce = Hex.ToHexString(nonce) }, KdfParams = new KdfParams { MemLimitKib = cfg.MemLimitKIB, OpsLimit = cfg.OpsLimit, Salt = Hex.ToHexString(salt), Parallelism = cfg.Parallelism } } }; return(wallet); }
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)); }
public async static Task SendSecretMessage(Stream s, byte[] key, byte[] message, CancellationToken token = default) { byte[] nonce = SecretBox.GenerateNonce(); byte[] ciphertext = SecretBox.Create(message, nonce, key); byte[] len = BitConverter.GetBytes((uint)ciphertext.Length); if (ciphertext.Length > MaxMessageLen) { throw new ArgumentOutOfRangeException($"Encrypted message would be {len} bytes long, which is larger than the limit of {MaxMessageLen}"); } await s.WriteAsync(len, 0, len.Length, token); await s.WriteAsync(nonce, 0, nonce.Length, token); await s.WriteAsync(ciphertext, 0, ciphertext.Length, token); }
private void metroButton2_Click(object sender, EventArgs e) { if (txt_name.Text == "" || txt_password.Text == "") { MessageBox.Show("Please provide Name and a password"); return; } try { //Create SqlConnection SqlConnection con = new SqlConnection(cs); SqlCommand cmd = new SqlCommand("INSERT INTO tbl_list (list_name,list_password,list_key,list_nonce) VALUES (@list_name,@list_password,@list_key,@list_nonce)", con); var list_nonce = SecretBox.GenerateNonce(); //24 byte nonce var list_key = SecretBox.GenerateKey(); //32 byte key var message = txt_password.Text; //encrypt the message var ciphertext = SecretBox.Create(message, list_nonce, list_key); cmd.Parameters.AddWithValue("@list_name", txt_name.Text); cmd.Parameters.AddWithValue("@list_password", ciphertext); cmd.Parameters.AddWithValue("@list_key", list_key); cmd.Parameters.AddWithValue("@list_nonce", list_nonce); Console.WriteLine(); Console.WriteLine("Original data: " + message); Console.WriteLine("Encrypting and writing to disk..."); con.Open(); int i = cmd.ExecuteNonQuery(); con.Close(); if (i != 0) { MessageBox.Show("Password Saved"); BindGridPasswords(); } } catch (Exception ex) { MessageBox.Show(ex.Message); } }
public void CreateTest() { // Randomly generate key and nonce from a separate libsodium implementation var key = "7IygDz/Hy8LC/wqXb6vsrpq7Vyn7mxCoh8nYOn5yVXc="; var nonce = "bUBIsnfvIv2Wo95SEkt4DIvBqZLGGBjV"; byte[] message = System.Text.Encoding.UTF8.GetBytes("Hello, World!"); String expectedCipherText = "cZFTGV7SrPeSdX5Q6b30PBEm5Y2uby/W5BSrrfU="; byte[] expectedCipherTextBytes = Convert.FromBase64String(expectedCipherText); byte[] bitKey = Convert.FromBase64String(key); byte[] bitNonce = Convert.FromBase64String(nonce); byte[] cipherText = SecretBox.Create(message, bitNonce, bitKey); Assert.AreEqual(expectedCipherText, Convert.ToBase64String(cipherText)); }
public static void EncryptPacket(ClientState state, int ID, int version, byte[] plainText) { byte[] cipherText; switch (ID) { case 10100: { cipherText = plainText; break; } case 10101: { var nonce = GenericHash.Hash(state.ClientKey.PublicKey.Concat(state.ServerKey).ToArray(), null, 24); plainText = state.ServerState.SessionKey.Concat(state.Nonce).Concat(plainText).ToArray(); cipherText = PublicKeyBox.Create(plainText, nonce, state.ClientKey.PrivateKey, state.ServerKey); cipherText = state.ClientKey.PublicKey.Concat(cipherText).ToArray(); break; } default: { cipherText = SecretBox.Create(plainText, state.Nonce, state.ServerState.SharedKey).Skip(16) .ToArray(); break; } } var packet = BitConverter.GetBytes(ID).Reverse().Skip(2) .Concat(BitConverter.GetBytes(cipherText.Length).Reverse().Skip(1)) .Concat(BitConverter.GetBytes(version).Reverse().Skip(2)).Concat(cipherText).ToArray(); state.Socket.BeginSend(packet, 0, packet.Length, 0, SendCallback, state); }
public static void EncryptPacket(Socket socket, ServerState state, int messageId, int unknown, byte[] plainText) { byte[] cipherText; if (messageId == 20100 || (messageId == 20103 && state.sharedKey == null)) { cipherText = plainText; } else if (messageId == 20103 || messageId == 20104) { byte[] nonce = GenericHash.Hash(state.clientState.nonce.Concat(state.clientKey).Concat(state.serverKey.PublicKey).ToArray(), null, 24); plainText = state.nonce.Concat(state.sharedKey).Concat(plainText).ToArray(); cipherText = PublicKeyBox.Create(plainText, nonce, state.serverKey.PrivateKey, state.clientKey); } else { // nonce was already incremented in ClientCrypto.DecryptPacket cipherText = SecretBox.Create(plainText, state.nonce, state.sharedKey).Skip(16).ToArray(); } byte[] packet = BitConverter.GetBytes(messageId).Reverse().Skip(2).Concat(BitConverter.GetBytes(cipherText.Length).Reverse().Skip(1)).Concat(BitConverter.GetBytes(unknown).Reverse().Skip(2)).Concat(cipherText).ToArray(); socket.BeginSend(packet, 0, packet.Length, 0, new AsyncCallback(SendCallback), state); }
public static Dictionary <string, string> Encrypt(string message, string secretKey) { byte[] nonce = GenerateNonce(); byte[] secret_bytes; if (!Utils.IsBase64(secretKey)) { secret_bytes = Encoding.ASCII.GetBytes(secretKey); } else { secret_bytes = Convert.FromBase64String(secretKey); } var crypt = SecretBox.Create(message, nonce, secret_bytes); return(new Dictionary <string, string>() { { "nonce", Convert.ToBase64String(nonce) }, { "crypt", Convert.ToBase64String(crypt) } }); }