目录
对于逆向来说,了解常见的加密算法可以让我们平时在逆向的时候可以更快更准确地找到目标加密算法。比如你发现加密出来的结果是base64或者是16进制的,可以猜测是AES或者RSA,又或者发现是16位或者32位的16进制加密结果的可以猜测是md5,然后这都是在逆向的时候初步的判断,具体还是需要断点调试。
常见的加密分为三类:摘要算法、对称加密、非对称加密
一、摘要算法
摘要算法是指把任意长度的输入消息数据转化为固定长度的输出数据的一种密码算法,又称为散列函数 、 哈希函数 、 杂凑函数 、单向函数等。
摘要算法所产生的固定长度的输出数据称为摘要值、散列值或哈希值。
常用在不可还原的密码存储、信息完整性校验等
摘要算法主要分为三大类
- MD(Message Digest,消息摘要算法),主要包括 MD2、MD4、MD5
- SHA-1(Secure Hash Algorithm,安全散列算法),主要包括SHA-1、SHA-2 系列(SHA-1 的衍生算法,包含 SHA-224、SHA-256、SHA-384、SHA-512)
- MAC(Message Authentication Code,消息认证码算法)主要包括 HmacMD5、HmacSHA1、HmacSHA256、HmacSHA384 和 HmacSHA512 算法
逆向中常见的是:MD5(16/32位)、SHA-1(40位)、SHA-256(64位)、SHA-512(128位)
Node.js加密代码:
const crypto = require('crypto');
function encryptHash(data, algorithm) {
/*
data : 待加密/解密的数据,
algorithm : 和加密模式
*/
const hash = crypto.createHash(algorithm);
hash.update(data);
return hash.digest('hex');
}
const data = 'Hello World!';
console.log('MD5:', encryptHash(data, 'md5'));
console.log('SHA1:', encryptHash(data, 'sha1'));
console.log('SHA256:', encryptHash(data, 'sha256'));
console.log('SHA512:', encryptHash(data, 'sha512'));
Python加密代码:
import hashlib
def encrypt_hash(data, algorithm):
# data : 待加密/解密的数据,
# algorithm : 和加密模式
hash = hashlib.new(algorithm)
hash.update(data.encode())
return hash.hexdigest()
data = 'Hello World!'
print('MD5:', encrypt_hash(data, 'md5'))
print('SHA1:', encrypt_hash(data, 'sha1'))
print('SHA256:', encrypt_hash(data, 'sha256'))
print('SHA512:', encrypt_hash(data, 'sha512'))
二、对称加密
对称加密是指加密秘钥和解密秘钥相同的加密算法,又称为秘密秘钥算法或单密钥算法
常见的对称加密:AES、SM1(国密)、SM4(国密)、DES、3DES、IDEA、RC2等
对称加密的优缺点:
优点:
- 加密解密速度快,适合对大量数据进行加密
- 实现简单,加密解密的算法相同
缺点:
- 密钥管理困难,需要安全地分发和存储密钥
- 密钥泄露后,所有加密数据都将失去保护
Node.js的AES加密代码:
1.使用使用crypto库
// 使用crypto
const crypto = require('crypto');
// ----------------------------------- crypto AES解密 -------------------------------------------------
function encryptAES(data, key, iv, algorithm) {
/*
data : 待加密/解密的数据,
key : 密钥,
iv : 初始化向量(IV),
algorithm : 和加密模式
*/
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update(data, 'utf8', 'hex');
encrypted += cipher.final('hex');
return encrypted;
}
// ----------------------------------- crypto AES加密 -------------------------------------------------
function decryptAES(data, key, iv, algorithm) {
/*
data : 待加密/解密的数据,
key : 密钥,
iv : 初始化向量(IV),
algorithm : 和加密模式
*/
const decipher = crypto.createDecipheriv(algorithm, key, iv);
let decrypted = decipher.update(data, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
const data = 'Hello World!';
const key = '0123456789abcdef0123456789abcdef';
const iv = '0123456789abcdef';
const algorithm = 'aes-256-cbc';
const encrypted = encryptAES(data, key, iv, algorithm);
console.log('Encrypted:', encrypted);
const decrypted = decryptAES(encrypted, key, iv, algorithm);
console.log('Decrypted:', decrypted);
2.使用crypto-js库
const CryptoJS = require('crypto-js');
// ----------------------------------- crypto-js AES解密 -------------------------------------------------
function encryptAES(data, key, iv, mode, padding) {
/*
待加密的数据 data、密钥 key、初始化向量 iv、加密模式 mode 和填充方式 padding。
其中,key 和 iv 都需要转换为 WordArray 格式,使用 CryptoJS.enc.Utf8.parse 方法实现。
mode 和 padding 都可以通过选项对象来设置,选项对象中还包括 iv 属性
*/
// 将密钥和IV转换为WordArray格式
const keyWordArray = CryptoJS.enc.Utf8.parse(key);
const ivWordArray = CryptoJS.enc.Utf8.parse(iv);
// 使用选项对象设置加密方式、填充方式和IV
const options = {
mode: CryptoJS.mode[mode],
padding: CryptoJS.pad[padding],
iv: ivWordArray,
};
// 对数据进行加密
const encrypted = CryptoJS.AES.encrypt(data, keyWordArray, options);
// 将加密后的数据转换为Base64字符串格式
const ciphertext = encrypted.ciphertext.toString(CryptoJS.enc.Base64);
return ciphertext;
}
// ----------------------------------- crypto-js AES解密 -------------------------------------------------
function decryptAES(ciphertext, key, iv, mode, padding) {
/*
密文 ciphertext、密钥 key、初始化向量 iv、加密模式 mode 和填充方式 padding。
与加密函数类似,key 和 iv 都需要转换为 WordArray 格式,使用 CryptoJS.enc.Utf8.parse 方法实现。
mode 和 padding 都可以通过选项对象来设置,选项对象中还包括 iv 属性
*/
// 将密钥和IV转换为WordArray格式
const keyWordArray = CryptoJS.enc.Utf8.parse(key);
const ivWordArray = CryptoJS.enc.Utf8.parse(iv);
// 使用选项对象设置加密方式、填充方式和IV
const options = {
mode: CryptoJS.mode[mode],
padding: CryptoJS.pad[padding],
iv: ivWordArray,
};
// 将Base64字符串格式的密文转换为WordArray格式
const ciphertextWordArray = CryptoJS.enc.Base64.parse(ciphertext);
// 对数据进行解密
const decrypted = CryptoJS.AES.decrypt(
{ ciphertext: ciphertextWordArray },
keyWordArray,
options
);
// 将解密后的数据转换为UTF-8字符串格式
const plaintext = decrypted.toString(CryptoJS.enc.Utf8);
return plaintext;
}
// 调用
const data = 'hello world';
const key = '0123456789abcdef';
const iv = '0123456789abcdef';
const mode = 'CBC';
const padding = 'Pkcs7';
const ciphertext = encryptAES(data, key, iv, mode, padding);
console.log(ciphertext);
const plaintext = decryptAES(ciphertext, key, iv, mode, padding);
console.log(plaintext);
Python的AES加密代码:
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import binascii
def encrypt_AES(data, key, iv, mode):
cipher = AES.new(key.encode(), mode, iv.encode())
encrypted = cipher.encrypt(pad(data.encode(), AES.block_size))
return binascii.hexlify(encrypted).decode()
def decrypt_AES(data, key, iv, mode):
cipher = AES.new(key.encode(), mode, iv.encode())
decrypted = cipher.decrypt(binascii.unhexlify(data))
return unpad(decrypted, AES.block_size).decode()
data = 'Hello World!'
key = '0123456789abcdef0123456789abcdef'
iv = '0123456789abcdef'
mode = AES.MODE_CBC
encrypted = encrypt_AES(data, key, iv, mode)
print('Encrypted:', encrypted)
decrypted = decrypt_AES(encrypted, key, iv, mode)
print('Decrypted:', decrypted)
三、非对称加密
非对称算法是指加密秘钥和解密秘钥不同的密码算法,又称为公开密码算法或公钥算法,该算法使用一个秘钥进行加密,用另外一个秘钥进行解密。
-
加密秘钥可以公开,又称为 公钥
-
解密秘钥必须保密,又称为 私钥
-
常见非对称算法包括 RSA、SM2(国密)、DH、DSA、ECDSA、ECC 等
优点:
- 密钥管理容易,只需保护好私钥即可
- 可以实现数字签名和身份验证等安全功能
缺点:
- 加密解密速度慢,适合对少量数据进行加密
- 密钥长度较长,需要更多的计算资源和存储空间
Node.js的RSA加密代码:
1.使用使用crypto库
const crypto = require('crypto');
// ----------------------------------- crypto RSA加密 -------------------------------------------------
function encryptRSA(data, publicKey) {
const bufferData = Buffer.from(data);
const encrypted = crypto.publicEncrypt(publicKey, bufferData);
return encrypted.toString('base64');
}
// ----------------------------------- crypto RSA解密 -------------------------------------------------
function decryptRSA(data, privateKey) {
const bufferData = Buffer.from(data, 'base64');
const decrypted = crypto.privateDecrypt(privateKey, bufferData);
return decrypted.toString();
}
const data = 'Hello World!';
const publicKey = `-----BEGIN PUBLIC KEY-----
-----END PUBLIC KEY-----`
const privateKey = `-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----`;
const encrypted = encryptRSA(data, publicKey);
console.log('Encrypted:', encrypted);
const decrypted = decryptRSA(encrypted, privateKey);
console.log('Decrypted:', decrypted);
// ----------------------------------- 生成公钥和私钥 -------------------------------------------------
// 生成公钥和私钥
// const { generateKeyPairSync } = require('crypto');
// const { publicKey, privateKey } = generateKeyPairSync('rsa', {
// modulusLength: 2048,
// publicKeyEncoding: {
// type: 'spki',
// format: 'pem',
// },
// privateKeyEncoding: {
// type: 'pkcs8',
// format: 'pem',
// },
// });
// console.log(publicKey)
// console.log(privateKey)
2.使用crypto-js库
// const CryptoJS = require('crypto-js');
const NodeRSA = require('node-rsa');
// ----------------------------------- node-rsa RSA加密 -------------------------------------------------
// RSA 加密函数
function encryptRSA(data, publicKey) {
// 创建 RSA 实例并导入公钥
const rsa = new NodeRSA();
rsa.importKey(publicKey, 'pkcs8-public-pem');
// 使用公钥加密数据
const ciphertext = rsa.encrypt(data, 'base64');
return ciphertext;
}
// ----------------------------------- node-rsa RSA解密 -------------------------------------------------
// RSA 解密函数
function decryptRSA(ciphertext, privateKey) {
// 创建 RSA 实例并导入私钥
const rsa = new NodeRSA();
rsa.importKey(privateKey, 'pkcs8-private-pem');
// 使用私钥解密数据
const plaintext = rsa.decrypt(ciphertext, 'utf8');
return plaintext;
}
const data = 'Hello, world!';
publicKey = ''
privateKey = ''
encrypted = encryptRSA(data, publicKey);
console.log('Encrypted:', encrypted);
decrypted = decryptRSA(encrypted, privateKey);
console.log('Decrypted:', decrypted);
Python的RSA加密代码:
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
def encrypt_RSA(data, public_key):
key = RSA.import_key(public_key)
cipher = PKCS1_OAEP.new(key)
encrypted = cipher.encrypt(data.encode())
return encrypted.hex()
def decrypt_RSA(data, private_key):
key = RSA.import_key(private_key)
cipher = PKCS1_OAEP.new(key)
decrypted = cipher.decrypt(bytes.fromhex(data))
return decrypted.decode()
data = 'Hello World!'
public_key = '''-----BEGIN PUBLIC KEY-----
-----END PUBLIC KEY-----'''
private_key = '''-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----'''
encrypted = encrypt_RSA(data, public_key)
print('Encrypted:', encrypted)
decrypted = decrypt_RSA(encrypted, private_key)
print('Decrypted:', decrypted)
另:对称加密和非对称加密的结果一般是16进制或者base64的格式。