安全兼容的加密示例
该存储库的创建是为了解决围绕Internet浮动的较差的加密代码示例数量不断增长。该存储库会随着时间的推移而扩展,以包括更多语言的示例。
截至2021年4月,在5个不同平台上有18种不同的兼容示例,用于15种不同的语言。
算法
- 加密:AES-128-GCM
- 键推导:PBKDF2
- pbkdf2底于哈希:SHA-256
由于Java无限强度政策,因此选择了具有128位密钥的AE,由于密码出口法而需要不超过128位的关键尺寸。虽然使用AES-128显示了示例,但可以通过更改algorithm_key_size(以及某些情况,algorithm_name)参数来琐碎地更改为256位AE。
兼容性
此处显示的每个示例均兼容在平台和/或语言之间。任何语言的加密条件的结果都可以通过任何语言解密。请不要提交拉动请求以获取与现有示例不兼容的示例。
方法
每个示例都以大约等同于以下签名的签名公开4种方法:
- 字符串EncryptString(明文:字符串,密码:字符串)
- 字符串decryptstring(ciphertext:字符串,密码:字符串)
- byte []加密(明文:byte [],键:字节[])
- byte []解密(ciphertext:byte [],键:字节[])
正如预期的那样,加密和解密方法可在运行并返回原始二进制数据。但是, *字符串方法采用字符串参数并返回基本64编码字符串。首先通过PBKDF2馈送密码参数。密码可以有任何长度,但是密钥必须长度为128位。您可以通过调整algorithm_key_size参数来更改AES密钥大小,在某些示例中,也可以更改algorithm_name参数。
注意:由于使用PBKDF2,二进制与字符串方法不兼容。
依赖性
| 语言 | 经过测试的版本 | 依赖性 | 笔记 |
|---|---|---|---|
| 爪哇 | Java 8 JRE | ||
| 科特林 | Java 8 JRE | ||
| JavaScript(节点) | Nodejs 8.4.0 | 在8.4.0上测试,但最早在4.0.0中得到支持 | |
| JavaScript(浏览器) | 需要base64-js | 使用WebCrypto API,请在使用此示例之前确保浏览器支持。 | |
| JavaScript(SJCL) | 需要Stanford JavaScript加密图书馆 | 不会异步运行。 | |
| 去 | 走1.9 | golang.org/x/crypto/pbkdf2 | 在1.9上进行了测试,但在早期版本中得到了支持。 |
| Python | v3.6.4 | 需要pycryptodome | 不支持Python 2。 |
| 红宝石 | v2.4.4 | 使用openssl宝石 | |
| Visual Basic .NET | .NET 4.5 | 需要Bouncycastle。 | |
| C# | .NET 4.5 | 需要Bouncycastle。 | |
| c | 需要Openssl libssl-dev | 使用scee.h头文件。 | |
| C ++ | 需要C ++ 11编译器 | 需要Openssl libssl-dev | C示例的包装器。需要scee.h和scee_cpp.h |
| Objective-C | 需要Openssl libssl-dev | C示例的包装器。需要scee.h和scee_objc.h | |
| 锈 | V1.30.0 | 需要环V0.13.2和Base64 V0.9.3板条箱 | |
| 迅速 | Swift 4.0 | 需要SwiftGCM。 | 必须使用桥梁进行COMMONCRYPTO。 |
| php | 需要PHP 7 | 使用需要PHP 7的Random_Bytes。 | |
| 珀尔 | Perl 5 | 需要加密 |
测试向量
以下密码是使用给定密码加密标准的结果。如果您的实现可以使用您编写的代码进行加密和解密,并且还可以将下文的密文源分解为相同的给定结果,则适用于此存储库中。回想一下,由于随机生成的盐和nonce,未预期的加密串输出,它们仅用于测试解密。
| 密文 | 密码 | 明文 |
|---|---|---|
| CQJXSXQ6Y5EBTW6W98UQFGWDOPACCCKCY0L1QK5GJFHZNKVHP4+OUVXOIIGHI8MO1R8CAYL5T | DTY62MV2CV | XCBJBJD72Q |
| VTHH3Z6JQJPIDK0YLE4+/umpxqbqbqccmaijwmaecb7qfcyolacvj973zbnm51vcup5utuvlu3h | PL4WODJQ4K | SOJHSCM4QR |
| snqhdwnlcmjellkewntxbhzmj1u+chqkk5kdvd/fskssshw5b8y8y8y8sornvhdm78juaypgkleud | bzo8pueysy | NYZD53 -MOLT |
| 5emcwwsj6ygxblld6dfw8i+qxcwxz5g/laewuyv/duocgvxbw4zlmd1tsj4n07wbbohiju | Oziaxpfgyh | VW1QJB30MT |
| 7miunuhjjpalbihyka2v/ibh3aplff0pgw6hqad5tkluh/1M69MLQ9XIKVCGFTR0CYCSTFLU | gkldy5mmzt | 9Z19EFCTOZ |
| 0IQWBC8/1YVTSL2DOG6AXAGFXVYPSV1BCBNDE06C7NL9R9REITN3NW18+ZUMC = | 空字符串 | 空字符串 |
C示例
C示例需要更多的努力来理解和使用,因为相对于Base64填充的缓冲尺寸变化。下面的示例显示了如何使用crypt_string_get_length来确定需要分配哪个缓冲区以存储结果。
#include \"SCEE.h\" #include <stdio.h> int main ( int argc , char * argv []) { // Our plaintext and password. unsigned char plaintext [] = \"Hello, World!\" ; unsigned char password [] = \"OddShapelyOak7332\" ; // Make enough space for our ciphertext. // Note that scee_crypt_string_get_length will give us the size of the buffer we // need INCLUDING the null character. size_t ct_length = scee_crypt_string_get_length ( strlen ( plaintext ), SCEE_CRYPT_ENCRYPT ); unsigned char ciphertext [ ct_length ]; // Encryption. // The operation places the null character at the end of the buffer for us. int r = scee_encrypt_string ( plaintext , strlen ( plaintext ), password , strlen ( password ), ciphertext ); if ( r != SCEE_OK ) { return 1 ; } // Output for Encryption. printf ( \"Ciphertext Buffer Size: %zu\\n\" , ct_length ); printf ( \"Ciphertext strlen : %zu\\n\" , strlen ( ciphertext )); printf ( \"Ciphertext : %s\\n\\n\" , ciphertext ); // Make enough space for our plaintext again. // Note that because of base64 padding, scee_crypt_string_get_length will // usually tell us that we need more space than we do. We can get the // actual length of the plaintext after we decrypt. size_t pt_max_length = scee_crypt_string_get_length ( strlen ( ciphertext ), SCEE_CRYPT_DECRYPT ); size_t pt_actual_length ; unsigned char plaintext2 [ pt_max_length ]; // Decryption. // The operation places the null character at the end of the buffer for us. r = scee_decrypt_string ( ciphertext , strlen ( ciphertext ), password , strlen ( password ), plaintext2 , & pt_actual_length ); if ( r != SCEE_OK ) { return 1 ; } // Output for Decryption. printf ( \"Plaintext Buffer Size: %zu\\n\" , pt_max_length ); printf ( \"Plaintext Actual Size: %zu\\n\" , pt_actual_length ); printf ( \"Plaintext strlen : %zu\\n\" , strlen ( plaintext )); printf ( \"Plaintext : %s\\n\\n\" , plaintext ); return 0 ; }
