added symmetric encrypt/decrypt support
This commit is contained in:
parent
1aeb224be8
commit
c6325a9925
@ -1,8 +1,8 @@
|
||||
using System.IO;
|
||||
using System;
|
||||
using Sodium;
|
||||
using treasurechest.STDIOWrapper;
|
||||
using getpass;
|
||||
using ShannonEntropyCal;
|
||||
|
||||
namespace treasurechestCLI{
|
||||
|
||||
@ -10,8 +10,8 @@ namespace treasurechestCLI{
|
||||
public static void EncryptMessage(){
|
||||
int choice = 0;
|
||||
int counter = 1;
|
||||
byte[] key = new byte[32];
|
||||
string message;
|
||||
string passphrase;
|
||||
string encrypted;
|
||||
|
||||
translations.Strings strings = new translations.Strings();
|
||||
@ -53,8 +53,9 @@ namespace treasurechestCLI{
|
||||
catch(System.NullReferenceException){
|
||||
continue;
|
||||
}
|
||||
passphrase = GetPass.getPass(strings.PASSPHRASE);
|
||||
encrypted =
|
||||
key = SecretBox.GenerateKey();
|
||||
//encrypted =
|
||||
|
||||
}
|
||||
else if (choice == encryptMenuOptions.Length){
|
||||
break;
|
||||
|
85
tests/testSymmetric.cs
Normal file
85
tests/testSymmetric.cs
Normal file
@ -0,0 +1,85 @@
|
||||
using NUnit.Framework;
|
||||
using chestcrypto.symmetric;
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using Sodium;
|
||||
|
||||
namespace SymmetricTests
|
||||
{
|
||||
public class Tests
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDecrypt()
|
||||
{
|
||||
byte[] message = UTF8Encoding.UTF8.GetBytes("Hello world");
|
||||
byte[] message2 = UTF8Encoding.UTF8.GetBytes("Hello worl2");
|
||||
int nonceSize = 24;
|
||||
byte[] nonce = SecretBox.GenerateNonce();
|
||||
byte[] key = SecretBox.GenerateKey();
|
||||
byte[] encrypted = SecretBox.Create(message, nonce, key);
|
||||
byte[] both = new byte[nonceSize + encrypted.Length];
|
||||
Buffer.BlockCopy(nonce, 0, both, 0, nonce.Length);
|
||||
Buffer.BlockCopy(encrypted, 0, both, nonce.Length, encrypted.Length);
|
||||
Assert.IsTrue(both.Length >= message.Length + 24);
|
||||
Assert.IsTrue(Enumerable.SequenceEqual(Symmetric.decrypt(both, key), message));
|
||||
Assert.IsFalse(Enumerable.SequenceEqual(Symmetric.decrypt(both, key), message2));
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEncryptBytesNoKey()
|
||||
{
|
||||
byte[] message = UTF8Encoding.UTF8.GetBytes("Hello world");
|
||||
byte[] message2 = UTF8Encoding.UTF8.GetBytes("Hello worl2");
|
||||
(byte[] encrypted, byte[] key) = Symmetric.encrypt(message);
|
||||
int nonceSize = 24;
|
||||
byte[] justCiphertext = new byte[encrypted.Length - nonceSize];
|
||||
|
||||
byte[] nonce = new byte[nonceSize];
|
||||
int counter = 0;
|
||||
for (int i = 0; i < encrypted.Length; i++){
|
||||
if (i < nonceSize){
|
||||
nonce[i] = encrypted[i];
|
||||
continue;
|
||||
}
|
||||
justCiphertext[counter] = encrypted[i];
|
||||
counter += 1;
|
||||
}
|
||||
Assert.IsTrue(Enumerable.SequenceEqual(SecretBox.Open(justCiphertext, nonce, key), message));
|
||||
Assert.IsFalse(Enumerable.SequenceEqual(SecretBox.Open(justCiphertext, nonce, key), message2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEncryptBytes()
|
||||
{
|
||||
byte[] message = UTF8Encoding.UTF8.GetBytes("Hello world");
|
||||
byte[] message2 = UTF8Encoding.UTF8.GetBytes("Hello worl2");
|
||||
byte[] key = SecretBox.GenerateKey();
|
||||
byte[] encrypted = Symmetric.encrypt(message, key);
|
||||
int nonceSize = 24;
|
||||
byte[] justCiphertext = new byte[encrypted.Length - nonceSize];
|
||||
|
||||
byte[] nonce = new byte[nonceSize];
|
||||
int counter = 0;
|
||||
for (int i = 0; i < encrypted.Length; i++){
|
||||
if (i < nonceSize){
|
||||
nonce[i] = encrypted[i];
|
||||
continue;
|
||||
}
|
||||
justCiphertext[counter] = encrypted[i];
|
||||
counter += 1;
|
||||
|
||||
}
|
||||
Assert.IsTrue(Enumerable.SequenceEqual(SecretBox.Open(justCiphertext, nonce, key), message));
|
||||
Assert.IsFalse(Enumerable.SequenceEqual(SecretBox.Open(justCiphertext, nonce, key), message2));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
|
||||
using System.Text;
|
||||
using Sodium;
|
||||
|
||||
namespace chestcrypto{
|
||||
|
||||
namespace kdf{
|
||||
public class DeterministicSymmetricKey{
|
||||
// Test
|
||||
public static byte[] generate(string passphrase, bool extraSensitive=false){
|
||||
var nonce = SecretBox.GenerateNonce();
|
||||
int strength = 2;
|
||||
if (extraSensitive){
|
||||
strength = 3;
|
||||
}
|
||||
return PasswordHash.ArgonHashBinary(Encoding.UTF8.GetBytes(passphrase), // Passphrase converted to bytes
|
||||
PasswordHash.ArgonGenerateSalt(), // Salt
|
||||
strength, strength,
|
||||
32);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
using Sodium;
|
||||
using System;
|
||||
using chestcrypto.kdf;
|
||||
namespace treasurechest{
|
||||
|
||||
namespace symmetric{
|
||||
|
||||
public class EncryptWithPassphrase{
|
||||
/* Class name is somewhat misleading as we actually derive a key from a string pass and use the key for secret key crypto*/
|
||||
public static byte[] encrypt(byte[] data, string passphrase, bool extraSensitive = false){
|
||||
byte[] key = DeterministicSymmetricKey.generate(passphrase, extraSensitive);
|
||||
return SecretBox.Create(data, SecretBox.GenerateNonce(), key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
23
treasurechest/chestcrypto/symmetric/exceptions.cs
Normal file
23
treasurechest/chestcrypto/symmetric/exceptions.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
namespace chestcrypto{
|
||||
|
||||
namespace exceptions{
|
||||
public class InvalidKeyLength : Exception
|
||||
{
|
||||
public InvalidKeyLength()
|
||||
{
|
||||
}
|
||||
|
||||
public InvalidKeyLength(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public InvalidKeyLength(string message, Exception inner)
|
||||
: base(message, inner)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
45
treasurechest/chestcrypto/symmetric/symmetric-encryption.cs
Normal file
45
treasurechest/chestcrypto/symmetric/symmetric-encryption.cs
Normal file
@ -0,0 +1,45 @@
|
||||
using System.Collections.Generic;
|
||||
using Sodium;
|
||||
|
||||
namespace chestcrypto{
|
||||
|
||||
namespace symmetric{
|
||||
|
||||
public class Symmetric{
|
||||
|
||||
public static byte[] encrypt(byte[] plaintext, byte[] key){
|
||||
if (key.Length != 32){
|
||||
throw new exceptions.InvalidKeyLength();
|
||||
}
|
||||
List<byte> encrypted = new List<byte>();
|
||||
byte[] nonce = SecretBox.GenerateNonce();
|
||||
encrypted.AddRange(nonce);
|
||||
byte[] ciphertext = SecretBox.Create(plaintext, nonce, key);
|
||||
encrypted.AddRange(ciphertext);
|
||||
return encrypted.ToArray();
|
||||
}
|
||||
public static (byte[] ciphertext, byte[] key) encrypt(byte[] plaintext){
|
||||
byte[] key = SecretBox.GenerateKey();
|
||||
return (encrypt(plaintext, key), key);
|
||||
}
|
||||
|
||||
public static byte[] decrypt(byte[] ciphertext, byte[] key){
|
||||
// Nonce is first 24 bytes of ciphertext, unencrypted (this is safe according to libsodium docs)
|
||||
int nonceSize = 24;
|
||||
byte[] nonce = new byte[nonceSize];
|
||||
List<byte> message = new List<byte>();
|
||||
for (int i = 0; i < ciphertext.Length; i++){
|
||||
if (i < nonceSize){
|
||||
nonce[i] = ciphertext[i];
|
||||
continue;
|
||||
}
|
||||
message.Add(ciphertext[i]);
|
||||
}
|
||||
return SecretBox.Open(message.ToArray(), nonce, key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
16
treasurechest/simplepack/Packed.cs
Normal file
16
treasurechest/simplepack/Packed.cs
Normal file
@ -0,0 +1,16 @@
|
||||
namespace chestcrypto{
|
||||
|
||||
namespace simplepack{
|
||||
|
||||
public class Packed{
|
||||
//private string
|
||||
//public override string ToString(){
|
||||
//}
|
||||
public Packed(){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Base58Check" Version="0.2.0" />
|
||||
<PackageReference Include="MessagePack" Version="2.1.115" />
|
||||
<PackageReference Include="niceware" Version="0.1.0.1" />
|
||||
<PackageReference Include="Sodium.Core" Version="1.2.3" />
|
||||
</ItemGroup>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user