
Simple and sane cryptographic wrapper library.
AdvSim.Cryptography NuGet 包含一组可复用的加密封装函数,这些函数配置了合理的默认值,并且易于使用。更多详细信息请参见下方各个子标题。
AdvSim.Cryptography NuGet 支持多种 .Net 版本。通常,库中包含的函数在各类目标框架上都有良好的覆盖。当函数仅限于特定框架时,会添加一个徽章以突出显示该依赖关系。
NuGet 地址: https://www.nuget.org/packages/AdvSim.Cryptography
当密钥材料作为加密构造函数的一部分提供时,将使用 Rfc2898DeriveBytes 返回伪随机字节数组,用于为加密和解密操作提供种子。这些字节数组质量很高,同时还能确保使用相同密钥材料调用相同函数会产生相同的伪随机种子。
该函数接收一个字节数组,并使用构造函数中提供的密钥材料对其进行加密或解密。完成后将返回一个字节数组。
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 支持 NuGet 中可用的所有 .Net 版本。然而,由于一些非常值得商榷的 .Net 设计决策,要在所有受支持的目标之间实现互操作并非易事。
因此,Framework < .Net 4.7 与其他所有版本之间存在实现差异。两个客户端应属于同一组才能成功执行密钥交换。例如,如果您需要一个客户端运行在 .Net 6 上,另一个运行在 .Net 4.5.1 上,则应改用 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 分钟内有效。这些数字机密还可用于为对称加密算法的轮换密钥动态生成种子。如果客户端在不同机器上使用相同的种子,它们将收到相同的 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);