
Simple and sane cryptographic wrapper library.
Пакет AdvSim.Cryptography NuGet содержит набор функций-обёрток для криптографии, которые можно переиспользовать, настроены с разумными значениями по умолчанию и просты в использовании. Более подробные сведения доступны в разделах ниже.
Пакет AdvSim.Cryptography NuGet поддерживает множество версий .Net. Как правило, функции библиотеки хорошо покрывают целевые платформы. Для функций, доступных только в определённых платформах, добавлен значок, чтобы подчеркнуть эту зависимость.
URL-адрес NuGet: https://www.nuget.org/packages/AdvSim.Cryptography
Когда ключевой материал передаётся в криптографический конструктор, для получения псевдослучайных байтовых массивов, используемых для инициализации операций шифрования и дешифрования, применяется Rfc2898DeriveBytes. Эти байтовые массивы имеют высокое качество и при этом гарантируют, что вызов одной и той же функции с одним и тем же ключевым материалом приведёт к одному и тому же псевдослучайному заполнению (seed).
Эта функция принимает байтовый массив и шифрует или дешифрует его с использованием ключевого материала, переданного в конструктор. По завершении она возвращает байтовый массив.
AES test = new AES("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Эта функция принимает байтовый массив и шифрует или дешифрует его с использованием ключевого материала, переданного в конструктор. По завершении она возвращает байтовый массив.
TripleDES test = new TripleDES("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Эта функция принимает байтовый массив и шифрует или дешифрует его с использованием ключевого материала, переданного в конструктор. По завершении она возвращает байтовый массив.
RC4 test = new RC4("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Эта функция принимает байтовый массив и шифрует или дешифрует его с использованием ключевого материала, переданного в конструктор. По завершении она возвращает байтовый массив.
RC2 test = new RC2("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Эта функция принимает байтовый массив и шифрует или дешифрует его с использованием ключевого материала, переданного в конструктор. По завершении она возвращает байтовый массив.
MultiXOR test = new MultiXOR("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Эта функция принимает байтовый массив и шифрует или дешифрует его с использованием ключевого материала, переданного в конструктор. По завершении она возвращает байтовый массив.
XTEA test = new XTEA("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Обратите внимание, что в v2.0.0 ECDH поддерживается во всех версиях .Net, доступных в NuGet. Однако из-за некоторых весьма сомнительных архитектурных решений .Net обеспечить совместимость между всеми поддерживаемыми целевыми платформами непросто.
В результате существуют различия в реализации между Framework < .Net 4.7 и всеми остальными средами. Оба клиента должны относиться к одной группе, чтобы успешно выполнить обмен ключами. Если, например, один клиент должен работать на .Net 6, а другой на .Net 4.5.1, то вместо ECDH следует использовать RSA.
Чтобы узнать больше о версионировании .Net, вы можете обратиться к следующему ресурсу.
Framework < .Net 4.7
Эти целевые платформы поддерживают только nistP256 и могут использовать библиотеку следующим образом.
// Initialize both clients
ECDH test1 = new ECDH();
ECDH test2 = new ECDH();
// Exchange public keys
Byte[] bPublic1 = test1.GetPublicKeyArray();
Byte[] bPublic2 = test2.GetPublicKeyArray();
// Derive
test1.DeriveSharedKey(bPublic2);
test2.DeriveSharedKey(bPublic1);
// Encrypt / Decrypt
Byte[] bEncrypted1 = test1.Encrypt(bTestData);
Byte[] bDecrypted2 = test2.Decrypt(bEncrypted1);
.Net 4.7+ || Standard 2.1 || .Net 6
Эти целевые платформы принимают кривую в качестве аргумента конструктора.
public enum ECCurveType
{
brainpoolP160r1,
brainpoolP160t1,
brainpoolP192r1,
brainpoolP192t1,
brainpoolP224r1,
brainpoolP224t1,
brainpoolP256r1,
brainpoolP256t1,
brainpoolP320r1,
brainpoolP320t1,
brainpoolP384r1,
brainpoolP384t1,
brainpoolP512r1,
brainpoolP512t1,
nistP256,
nistP384,
nistP521
}
Пример использования приведён ниже.
// Initialize both clients
ECDH test1 = new ECDH(ECDH.ECCurveType.nistP521);
ECDH test2 = new ECDH(ECDH.ECCurveType.nistP521);
// Exchange public keys
Byte[] bPublic1 = test1.GetPublicKeyArray();
Byte[] bPublic2 = test2.GetPublicKeyArray();
// Derive
test1.DeriveSharedKey(bPublic2);
test2.DeriveSharedKey(bPublic1);
// Encrypt / Decrypt
Byte[] bEncrypted1 = test1.Encrypt(bTestData);
Byte[] bDecrypted2 = test2.Decrypt(bEncrypted1);
Обратите внимание, что данная функциональность обязательно требует двух клиентов, поскольку для получения общего секрета не требуется обмен открытыми ключами, как в случае с ECDH. Разумеется, как и выше, вы можете отправить свой открытый ключ по сети другому клиенту, который затем сможет зашифровать данные, которые сможете расшифровать только вы.
RSA test = new RSA();
Byte[] bPublicKey = test.GetPublicKeyArray();
Byte[] bEncrypted = test.Encrypt(bPublicKey, bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Шифрование и дешифрование данных привязано к данной машине. Данные не могут быть расшифрованы за пределами хоста.
// Without entropy
DPAPI test = new DPAPI();
Byte[] bEncrypted = test.EncryptUserDPAPI(bTestData);
Byte[] bDecrypted = test.DecryptUserDPAPI(bEncrypted);
// With entropy
DPAPI test = new DPAPI("Lovecraft");
Byte[] bEncrypted = test.EncryptUserDPAPI(bTestData);
Byte[] bDecrypted = test.DecryptUserDPAPI(bEncrypted);
Шифрование и дешифрование данных привязано к текущему пользователю. Данные не могут быть расшифрованы в контексте другого пользователя.
// Without entropy
DPAPI test = new DPAPI();
Byte[] bEncrypted = test.EncryptMachineDPAPI(bTestData);
Byte[] bDecrypted = test.DecryptMachineDPAPI(bEncrypted);
// With entropy
DPAPI test = new DPAPI("Lovecraft");
Byte[] bEncrypted = test.EncryptMachineDPAPI(bTestData);
Byte[] bDecrypted = test.DecryptMachineDPAPI(bEncrypted);
Одноразовый пароль на основе времени (TOTP) может использоваться как дополнительная проверка подлинности при выполнении действий. TOTP, генерируемые библиотекой, действительны в течение полной минуты по UtcNow. Эти числовые секреты также можно использовать для динамической инициализации сменяющихся ключей в алгоритмах симметричного шифрования. Если клиенты используют одинаковое начальное значение (seed) на разных машинах, они будут получать одинаковый TOTP.
// Generate a TOTP using a string seed
TOTP test = new TOTP("Lovecraft");
Console.WriteLine("[+] TOPT Code : " + oOTP.Code);
Console.WriteLine("[+] TOPT Last Code: " + oOTP.LastCode);
Console.WriteLine("[+] TOPT Validity : " + oOTP.Seconds);
// Validate TOTP based on string seed
Boolean bValid = test.ValidateTOTP("Lovecraft", oTOTP.Code);
// Validate TOTP with forgiveness, this allows the previous TOTP
// to also be counted as valid
Boolean bValid = test.ValidateTOTP("Lovecraft", oTOTP.LastCode, true);