
Simple and sane cryptographic wrapper library.
El paquete NuGet AdvSim.Cryptography contiene un conjunto de funciones contenedoras criptográficas reutilizables, configuradas con valores predeterminados razonables y fáciles de usar. Encontrará más detalles en los distintos subapartados siguientes.
El paquete NuGet AdvSim.Cryptography admite una amplia variedad de versiones de .Net. En general, las funciones incluidas en la biblioteca tienen una buena cobertura en todos los frameworks de destino. Cuando las funciones están restringidas a frameworks específicos, se ha añadido una insignia para resaltar esa dependencia.
URL de NuGet: https://www.nuget.org/packages/AdvSim.Cryptography
Cuando el material de claves se proporciona como parte del constructor criptográfico, se utiliza Rfc2898DeriveBytes para devolver matrices de bytes pseudoaleatorias que siembran las operaciones de cifrado y descifrado. Estas matrices de bytes son de alta calidad y, al mismo tiempo, garantizan que llamar a la misma función con el mismo material de claves produzca la misma semilla pseudoaleatoria.
Esta función toma una matriz de bytes y la cifra o descifra utilizando el material de claves proporcionado en el constructor. Al finalizar, devolverá una matriz de bytes.
AES test = new AES("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Esta función toma una matriz de bytes y la cifra o descifra utilizando el material de claves proporcionado en el constructor. Al finalizar, devolverá una matriz de bytes.
TripleDES test = new TripleDES("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Esta función toma una matriz de bytes y la cifra o descifra utilizando el material de claves proporcionado en el constructor. Al finalizar, devolverá una matriz de bytes.
RC4 test = new RC4("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Esta función toma una matriz de bytes y la cifra o descifra utilizando el material de claves proporcionado en el constructor. Al finalizar, devolverá una matriz de bytes.
RC2 test = new RC2("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Esta función toma una matriz de bytes y la cifra o descifra utilizando el material de claves proporcionado en el constructor. Al finalizar, devolverá una matriz de bytes.
MultiXOR test = new MultiXOR("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Esta función toma una matriz de bytes y la cifra o descifra utilizando el material de claves proporcionado en el constructor. Al finalizar, devolverá una matriz de bytes.
XTEA test = new XTEA("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Tenga en cuenta que en v2.0.0 ECDH es compatible con todas las versiones de .Net disponibles en el paquete NuGet. Sin embargo, debido a algunas decisiones de diseño de .Net realmente cuestionables, no es trivial conseguir interoperabilidad entre todos los destinos admitidos.
Como resultado, existen diferencias de implementación entre Framework < .Net 4.7 y el resto. Ambos clientes deben pertenecer al mismo grupo para poder realizar correctamente un intercambio de claves. Si, por ejemplo, necesita que un cliente esté en .Net 6 y otro en .Net 4.5.1, entonces debería usar RSA en su lugar.
Para comprender mejor el control de versiones de .Net, puede consultar el siguiente recurso.
Framework < .Net 4.7
Estos destinos solo admiten nistP256 y pueden usar la biblioteca de la siguiente manera.
// 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
Estos destinos aceptan una curva como argumento del constructor.
public enum ECCurveType
{
brainpoolP160r1,
brainpoolP160t1,
brainpoolP192r1,
brainpoolP192t1,
brainpoolP224r1,
brainpoolP224t1,
brainpoolP256r1,
brainpoolP256t1,
brainpoolP320r1,
brainpoolP320t1,
brainpoolP384r1,
brainpoolP384t1,
brainpoolP512r1,
brainpoolP512t1,
nistP256,
nistP384,
nistP521
}
El uso se muestra a continuación.
// 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);
Tenga en cuenta que esta funcionalidad no requiere necesariamente dos clientes, ya que las claves públicas no tienen que intercambiarse para derivar un secreto compartido como ocurre con ECDH. Por supuesto, como se indicó anteriormente, puede enviar su clave pública a otro cliente, que podrá cifrar datos que solo usted podrá descifrar.
RSA test = new RSA();
Byte[] bPublicKey = test.GetPublicKeyArray();
Byte[] bEncrypted = test.Encrypt(bPublicKey, bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Los datos que se cifran y descifran están restringidos a la máquina. Los datos no se pueden descifrar fuera del host.
// 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);
Los datos que se cifran y descifran están restringidos al usuario actual. Los datos no se pueden descifrar en un contexto de usuario diferente.
// 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);
Una contraseña de un solo uso basada en el tiempo (TOTP) puede utilizarse como comprobación adicional al realizar acciones para validar que son auténticas. Los TOTP generados por la biblioteca son válidos durante un minuto completo de UtcNow. Estos secretos numéricos también pueden utilizarse para sembrar dinámicamente claves rotatorias para algoritmos de cifrado simétrico. Si los clientes usan la misma semilla en distintas máquinas, recibirán el mismo 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);