
Simple and sane cryptographic wrapper library.
Das AdvSim.Cryptography NuGet enthält eine Reihe von kryptografischen Wrapper-Funktionen, die wiederverwendbar sind, mit sinnvollen Standardeinstellungen konfiguriert werden und einfach zu verwenden sind. Weitere Details finden Sie unter den verschiedenen Unterüberschriften unten.
Das AdvSim.Cryptography NuGet unterstützt eine Vielzahl von .Net-Versionen. Im Allgemeinen haben die in der Bibliothek enthaltenen Funktionen eine gute Abdeckung über die Ziel-Frameworks. Wo Funktionen auf bestimmte Frameworks beschränkt sind, wurde ein Badge hinzugefügt, um diese Abhängigkeit hervorzuheben.
NuGet-URL: https://www.nuget.org/packages/AdvSim.Cryptography
Wenn Schlüsselmaterial als Teil des kryptografischen Konstruktors bereitgestellt wird, wird Rfc2898DeriveBytes verwendet, um pseudozufällige Byte-Arrays zurückzugeben, die die Ver- und Entschlüsselungsoperationen seeden. Diese Byte-Arrays sind von hoher Qualität und stellen gleichzeitig sicher, dass der Aufruf derselben Funktion mit demselben Schlüsselmaterial zu demselben pseudozufälligen Seed führt.
Diese Funktion nimmt ein Byte-Array entgegen und verschlüsselt oder entschlüsselt es mithilfe des im Konstruktor bereitgestellten Schlüsselmaterials. Nach Abschluss gibt sie ein Byte-Array zurück.
AES test = new AES("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Diese Funktion nimmt ein Byte-Array entgegen und verschlüsselt oder entschlüsselt es mithilfe des im Konstruktor bereitgestellten Schlüsselmaterials. Nach Abschluss gibt sie ein Byte-Array zurück.
TripleDES test = new TripleDES("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Diese Funktion nimmt ein Byte-Array entgegen und verschlüsselt oder entschlüsselt es mithilfe des im Konstruktor bereitgestellten Schlüsselmaterials. Nach Abschluss gibt sie ein Byte-Array zurück.
RC4 test = new RC4("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Diese Funktion nimmt ein Byte-Array entgegen und verschlüsselt oder entschlüsselt es mithilfe des im Konstruktor bereitgestellten Schlüsselmaterials. Nach Abschluss gibt sie ein Byte-Array zurück.
RC2 test = new RC2("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Diese Funktion nimmt ein Byte-Array entgegen und verschlüsselt oder entschlüsselt es mithilfe des im Konstruktor bereitgestellten Schlüsselmaterials. Nach Abschluss gibt sie ein Byte-Array zurück.
MultiXOR test = new MultiXOR("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Diese Funktion nimmt ein Byte-Array entgegen und verschlüsselt oder entschlüsselt es mithilfe des im Konstruktor bereitgestellten Schlüsselmaterials. Nach Abschluss gibt sie ein Byte-Array zurück.
XTEA test = new XTEA("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Beachten Sie hier, dass ECDH in v2.0.0 über alle im NuGet verfügbaren .Net-Versionen unterstützt wird. Aufgrund einiger wirklich fragwürdiger .Net-Designentscheidungen ist es jedoch nicht trivial, Interop zwischen allen unterstützten Zielen zu erreichen.
Daher gibt es Implementierungsunterschiede zwischen Framework < .Net 4.7 und allen anderen. Beide Clients sollten in dieselbe Gruppe fallen, um einen Schlüsselaustausch erfolgreich durchzuführen. Wenn Sie beispielsweise einen Client unter .Net 6 und einen anderen unter .Net 4.5.1 benötigen, sollten Sie stattdessen RSA verwenden.
Weitere Informationen zur .Net-Versionsverwaltung finden Sie in der folgenden Ressource.
Framework < .Net 4.7
Diese Ziele unterstützen nur nistP256 und können die Bibliothek wie folgt verwenden.
// 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
Diese Ziele akzeptieren eine Kurve als Argument für den Konstruktor.
public enum ECCurveType
{
brainpoolP160r1,
brainpoolP160t1,
brainpoolP192r1,
brainpoolP192t1,
brainpoolP224r1,
brainpoolP224t1,
brainpoolP256r1,
brainpoolP256t1,
brainpoolP320r1,
brainpoolP320t1,
brainpoolP384r1,
brainpoolP384t1,
brainpoolP512r1,
brainpoolP512t1,
nistP256,
nistP384,
nistP521
}
Die Verwendung ist unten dargestellt.
// 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);
Beachten Sie, dass diese Funktionalität nicht zwingend zwei Clients erfordert, da – anders als bei ECDH – keine öffentlichen Schlüssel ausgetauscht werden müssen, um ein gemeinsames Geheimnis abzuleiten. Natürlich können Sie, wie oben beschrieben, Ihren öffentlichen Schlüssel über das Netzwerk an einen anderen Client senden, der dann Daten verschlüsseln kann, die nur Sie entschlüsseln können.
RSA test = new RSA();
Byte[] bPublicKey = test.GetPublicKeyArray();
Byte[] bEncrypted = test.Encrypt(bPublicKey, bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Daten, die verschlüsselt und entschlüsselt werden, sind an die Maschine gebunden. Daten können nicht außerhalb des Hosts entschlüsselt werden.
// 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);
Daten, die verschlüsselt und entschlüsselt werden, sind an den aktuellen Benutzer gebunden. Daten können nicht in einem anderen Benutzerkontext entschlüsselt werden.
// 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);
Ein zeitbasiertes Einmalpasswort (TOTP) kann als zusätzliche Prüfung bei der Durchführung von Aktionen verwendet werden, um deren Authentizität zu bestätigen. Die von der Bibliothek erzeugten TOTPs sind eine volle Minute gemäß UtcNow gültig. Diese numerischen Geheimnisse können auch verwendet werden, um rotierende Schlüssel für symmetrische Verschlüsselungsalgorithmen dynamisch zu seeden. Wenn Clients auf verschiedenen Maschinen denselben Seed verwenden, erhalten sie dasselbe 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);