Merge pull request #17366 from xsellier/feature/add-encrypt-decrypt-string

Add encrypt_text/decrypt_text function using aes256 algorithm (2.1.5)
This commit is contained in:
Rémi Verschelde 2018-03-23 11:35:07 +01:00 committed by GitHub
commit ddcea2a7dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 130 additions and 0 deletions

View File

@ -35,6 +35,8 @@
#include "ucaps.h"
#include "variant.h"
#include "thirdparty/misc/aes256.h"
#include "thirdparty/misc/base64.h"
#include "thirdparty/misc/md5.h"
#include "thirdparty/misc/sha256.h"
@ -2311,6 +2313,107 @@ String String::sha256_text() const {
return String::hex_encode_buffer(hash, 32);
}
String String::encrypt_text(const String &p_key) const {
// Validate key
String cs = p_key.md5_text();
ERR_FAIL_COND_V(cs.length() != 32, String());
Vector<uint8_t> key;
key.resize(32);
for (int i = 0; i < 32; i++) {
key[i] = cs[i];
}
// Prepare buffer
const CharType *clear_str = c_str();
Vector<uint8_t> encrypted_buf;
// Note:
// Converting extended ascii to char, 4 bytes to 1 (due to unsigned/signed types).
// This has to be done only in the encryption part.
size_t len = length() * 4;
if (len % 16) {
len += 16 - (len % 16);
}
encrypted_buf.resize(len);
zeromem(encrypted_buf.ptr(), len);
for (int i = 0; i < length() * 4; i++) {
encrypted_buf[i] = ((uint8_t *)clear_str)[i];
}
aes256_context ctx;
aes256_init(&ctx, key.ptr());
for (size_t i = 0; i < len; i += 16) {
aes256_encrypt_ecb(&ctx, &encrypted_buf[i]);
}
aes256_done(&ctx);
// Preparing encrypted buffer encoded in base64
len = encrypted_buf.size();
size_t b64len = len / 3 * 4 + 4 + 1;
Vector<uint8_t> encrypted_buf_base64;
encrypted_buf_base64.resize(b64len);
zeromem((char *)(&encrypted_buf_base64[0]), len);
size_t strlen = base64_encode((char *)(&encrypted_buf_base64[0]), (char *)(&encrypted_buf[0]), len);
encrypted_buf_base64[strlen] = 0;
String encrypted_str = (char *)&encrypted_buf_base64[0];
return encrypted_str;
}
String String::decrypt_text(const String &p_key) const {
// Validate key
String cs = p_key.md5_text();
ERR_FAIL_COND_V(cs.length() != 32, String());
Vector<uint8_t> key;
key.resize(32);
for (int i = 0; i < 32; i++) {
key[i] = cs[i];
}
// Prepare buffer, base64 to raw array
size_t strlen = length();
CharString cstr = utf8();
size_t len;
Vector<uint8_t> decrypted_buf;
{
decrypted_buf.resize(strlen / 4 * 3 + 1);
len = base64_decode((char *)(&decrypted_buf[0]), (char *)cstr.get_data(), strlen);
};
decrypted_buf.resize(len);
aes256_context ctx;
aes256_init(&ctx, key.ptr());
for (size_t i = 0; i < len; i += 16) {
aes256_decrypt_ecb(&ctx, &decrypted_buf[i]);
}
aes256_done(&ctx);
// decrypted_buf is originally stored using unsigned short, this is
// why we are casting it to CharType
String decrypted_str = (CharType *)&decrypted_buf[0];
return decrypted_str;
}
Vector<uint8_t> String::md5_buffer() const {
CharString cs = utf8();
@ -3099,6 +3202,7 @@ String String::humanize_size(size_t p_size) {
return String::num(p_size / divisor, digits) + prefix[prefix_idx];
}
bool String::is_abs_path() const {
if (length() > 1)

View File

@ -191,6 +191,10 @@ public:
uint64_t hash64() const; /* hash the string */
String md5_text() const;
String sha256_text() const;
String encrypt_text(const String &p_key) const;
String decrypt_text(const String &p_key) const;
Vector<uint8_t> md5_buffer() const;
Vector<uint8_t> sha256_buffer() const;

View File

@ -261,6 +261,8 @@ struct _VariantCall {
VCALL_LOCALMEM0R(String, hash);
VCALL_LOCALMEM0R(String, md5_text);
VCALL_LOCALMEM0R(String, sha256_text);
VCALL_LOCALMEM1R(String, encrypt_text);
VCALL_LOCALMEM1R(String, decrypt_text);
VCALL_LOCALMEM0R(String, md5_buffer);
VCALL_LOCALMEM0R(String, sha256_buffer);
VCALL_LOCALMEM0R(String, empty);
@ -1345,6 +1347,8 @@ void register_variant_methods() {
ADDFUNC0(STRING, INT, String, hash, varray());
ADDFUNC0(STRING, STRING, String, md5_text, varray());
ADDFUNC0(STRING, STRING, String, sha256_text, varray());
ADDFUNC1(STRING, STRING, String, encrypt_text, STRING, "key", varray());
ADDFUNC1(STRING, STRING, String, decrypt_text, STRING, "key", varray());
ADDFUNC0(STRING, RAW_ARRAY, String, md5_buffer, varray());
ADDFUNC0(STRING, RAW_ARRAY, String, sha256_buffer, varray());
ADDFUNC0(STRING, BOOL, String, empty, varray());

View File

@ -39294,6 +39294,15 @@
Perform a case-sensitive comparison to another string, return -1 if less, 0 if equal and +1 if greater.
</description>
</method>
<method name="decrypt_text">
<return type="String">
</return>
<argument index="0" name="key" type="String">
</argument>
<description>
Copy the String and return it decrypted.
</description>
</method>
<method name="empty">
<return type="bool">
</return>
@ -39301,6 +39310,15 @@
Return true if the string is empty.
</description>
</method>
<method name="encrypt_text">
<return type="String">
</return>
<argument index="0" name="key" type="String">
</argument>
<description>
Copy the String and return it encrypted.
</description>
</method>
<method name="ends_with">
<return type="bool">
</return>