
Simple and sane cryptographic wrapper library.
O NuGet AdvSim.Cryptography contém um conjunto de funções de wrapper criptográficas que são reutilizáveis, configuradas com padrões sensatos e fáceis de usar. Mais detalhes estão disponíveis nas diferentes subseções abaixo.
O NuGet AdvSim.Cryptography suporta uma grande variedade de versões do .Net. De modo geral, as funções incluídas na biblioteca têm boa cobertura entre os frameworks de destino. Quando as funções são restritas a frameworks específicos, um badge foi adicionado para destacar essa dependência.
URL do NuGet: https://www.nuget.org/packages/AdvSim.Cryptography
Quando o material de chave é fornecido como parte do construtor criptográfico, Rfc2898DeriveBytes é usado para retornar matrizes de bytes pseudoaleatórias para semear as operações de criptografia e descriptografia. Essas matrizes de bytes são de alta qualidade e também garantem que chamar a mesma função com o mesmo material de chave resulte na mesma semente pseudoaleatória.
Esta função recebe uma matriz de bytes e a criptografa ou descriptografa usando o material de chave fornecido no construtor. Ao concluir, retorna uma matriz de bytes.
AES test = new AES("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Esta função recebe uma matriz de bytes e a criptografa ou descriptografa usando o material de chave fornecido no construtor. Ao concluir, retorna uma matriz de bytes.
TripleDES test = new TripleDES("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Esta função recebe uma matriz de bytes e a criptografa ou descriptografa usando o material de chave fornecido no construtor. Ao concluir, retorna uma matriz de bytes.
RC4 test = new RC4("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Esta função recebe uma matriz de bytes e a criptografa ou descriptografa usando o material de chave fornecido no construtor. Ao concluir, retorna uma matriz de bytes.
RC2 test = new RC2("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Esta função recebe uma matriz de bytes e a criptografa ou descriptografa usando o material de chave fornecido no construtor. Ao concluir, retorna uma matriz de bytes.
MultiXOR test = new MultiXOR("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Esta função recebe uma matriz de bytes e a criptografa ou descriptografa usando o material de chave fornecido no construtor. Ao concluir, retorna uma matriz de bytes.
XTEA test = new XTEA("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Note aqui que, no v2.0.0, o ECDH é suportado em todas as versões do .Net disponíveis no NuGet. No entanto, devido a algumas decisões de design realmente questionáveis do .Net, não é trivial obter interoperabilidade entre todos os alvos suportados.
Como resultado, existem diferenças de implementação entre Framework < .Net 4.7 e todo o resto. Ambos os clientes devem pertencer ao mesmo grupo para realizar com êxito uma troca de chaves. Se, por exemplo, você precisar que um cliente esteja no .Net 6 e outro no .Net 4.5.1, use RSA em vez disso.
Para entender melhor sobre o versionamento do .Net, você pode consultar o seguinte recurso.
Framework < .Net 4.7
Esses alvos suportam apenas nistP256 e podem usar a biblioteca da seguinte forma.
// 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
Esses alvos recebem uma curva como argumento para o construtor.
public enum ECCurveType
{
brainpoolP160r1,
brainpoolP160t1,
brainpoolP192r1,
brainpoolP192t1,
brainpoolP224r1,
brainpoolP224t1,
brainpoolP256r1,
brainpoolP256t1,
brainpoolP320r1,
brainpoolP320t1,
brainpoolP384r1,
brainpoolP384t1,
brainpoolP512r1,
brainpoolP512t1,
nistP256,
nistP384,
nistP521
}
O uso é mostrado abaixo.
// 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);
Note que essa funcionalidade não requer necessariamente dois clientes, pois as chaves públicas não precisam ser trocadas para derivar um segredo compartilhado, como é o caso do ECDH. É claro que, como acima, você pode enviar sua chave pública pela rede para outro cliente, que então pode criptografar dados que somente você pode descriptografar.
RSA test = new RSA();
Byte[] bPublicKey = test.GetPublicKeyArray();
Byte[] bEncrypted = test.Encrypt(bPublicKey, bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
Os dados que são criptografados e descriptografados têm escopo restrito à máquina. Os dados não podem ser descriptografados fora do 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);
Os dados criptografados e descriptografados têm escopo restrito ao usuário atual. Os dados não podem ser descriptografados em um contexto de usuário 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);
Uma senha de uso único baseada em tempo (TOTP) pode ser usada como uma verificação adicional ao realizar ações para validar que elas são autênticas. Os TOTPs gerados pela biblioteca são válidos por um minuto completo de UtcNow. Esses segredos numéricos também podem ser usados para semear dinamicamente chaves rotativas para algoritmos de criptografia simétrica. Se os clientes usarem a mesma semente em máquinas diferentes, eles receberão o mesmo 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);