逆向中的密码基础
加密算法
MD5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public static void main(String[] args) throws Exception { MessageDigest md = MessageDigest.getInstance("MD5"); md.update("吾爱破解论坛".getBytes()); byte[] res = md.digest(); System.out.println(byteToHexString(res)); } public static String byteToHexString(byte[] by) { StringBuilder SB = new StringBuilder();
for (int k : by) { int j = k; if (k < 0) { j = k + 256; }
if (j < 16) { SB.append("0"); }
SB.append(Integer.toHexString(j)); } return SB.toString(); }
|
对称加密
定义: 加密和解密使用相同密钥的密码算法叫对称加解密算法,简称对称算法。对称算法速度快,通常在需要加密大量数据时使用。所谓对称,就是采用这种密码方法的双方使用同样的密钥进行加密和解密。
- DES(数据加密标准):DES是一种对称加密算法,使用56位密钥,将数据分成64位块,然后进行加密。由于DES的密钥长度比较短,易受到暴力破解攻击。
- 3DES(三重DES):3DES是基于DES算法的改进版本,使用三个56位的密钥,对数据进行三次加密,从而增加了加密强度。3DES比DES更加安全,但是加密速度较慢。
- AES(高级加密标准):AES是一种高级的对称加密算法,使用128、192或256位密钥,可以对不同长度的数据块进行加密。AES比DES和3DES更加安全,且加密速度更快。
- RC4:RC4是一种流加密算法,使用相同的密钥对数据进行加密和解密。RC4的密钥长度可以是40位、64位、128位等不同长度。RC4在实际应用中已经被证明存在漏洞,不再被推荐使用。
(1)AES加解密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; public class Aes { private static final String ALGORITHM = "AES"; private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding"; private static final String SECRET_KEY = "1234567wuaipojie"; public static void main(String[] args) throws Exception { String originalMessage = "吾爱破解论坛"; byte[] encryptedMessage = encrypt(originalMessage); System.out.println("加密结果: " + Base64.getEncoder().encodeToString(encryptedMessage)); String decryptedMessage = decrypt(encryptedMessage); System.out.println("解密结果: " + decryptedMessage); } private static byte[] encrypt(String message) throws Exception { SecretKeySpec key = new SecretKeySpec(SECRET_KEY.getBytes(), ALGORITHM); Cipher cipher = Cipher.getInstance(TRANSFORMATION); cipher.init(Cipher.ENCRYPT_MODE, key); return cipher.doFinal(message.getBytes()); } private static String decrypt(byte[] encryptedMessage) throws Exception { SecretKeySpec key = new SecretKeySpec(SECRET_KEY.getBytes(), ALGORITHM); Cipher cipher = Cipher.getInstance(TRANSFORMATION); cipher.init(Cipher.DECRYPT_MODE, key); return new String(cipher.doFinal(encryptedMessage)); } }
|
(2)DES加解密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; public class Des { private static final String ALGORITHM = "DES"; private static final String TRANSFORMATION = "DES/ECB/PKCS5Padding"; private static final String SECRET_KEY = "52pj2023"; public static void main(String[] args) throws Exception { String originalMessage = "吾爱破解论坛"; byte[] encryptedMessage = encrypt(originalMessage); System.out.println("加密结果: " + Base64.getEncoder().encodeToString(encryptedMessage)); String decryptedMessage = decrypt(encryptedMessage); System.out.println("解密结果: " + decryptedMessage); } private static byte[] encrypt(String message) throws Exception { SecretKeySpec key = new SecretKeySpec(SECRET_KEY.getBytes(), ALGORITHM); Cipher cipher = Cipher.getInstance(TRANSFORMATION); cipher.init(Cipher.ENCRYPT_MODE, key); return cipher.doFinal(message.getBytes()); } private static String decrypt(byte[] encryptedMessage) throws Exception { SecretKeySpec key = new SecretKeySpec(SECRET_KEY.getBytes(), ALGORITHM); Cipher cipher = Cipher.getInstance(TRANSFORMATION); cipher.init(Cipher.DECRYPT_MODE, key); return new String(cipher.doFinal(encryptedMessage)); } }
|
(3)RC4加密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.util.Base64;
public class Rc4 { private static final String ALGORITHM = "RC4"; private static final String SECRET_KEY = "1234567890abcdef";
public static void main(String[] args) throws Exception { String originalMessage = "吾爱破解论坛";
byte[] encryptedMessage = encrypt(originalMessage); System.out.println("加密结果: " + Base64.getEncoder().encodeToString(encryptedMessage));
String decryptedMessage = decrypt(encryptedMessage); System.out.println("解密结果: " + decryptedMessage); }
private static byte[] encrypt(String message) throws Exception { SecretKeySpec key = new SecretKeySpec(SECRET_KEY.getBytes(), ALGORITHM); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, key); return cipher.doFinal(message.getBytes()); }
private static String decrypt(byte[] encryptedMessage) throws Exception { SecretKeySpec key = new SecretKeySpec(SECRET_KEY.getBytes(), ALGORITHM); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, key); return new String(cipher.doFinal(encryptedMessage)); } }
|
非对称加密算法
定义: 非对称加密,也称为公钥加密,使用两个不同的密钥进行加密和解密,这两个密钥是一对,一个被称为公钥,一个被称为私钥。公钥可以随意分发给任何需要通信的人,而私钥则只能由密钥持有者保留。在非对称加密中,公钥用于加密消息,而私钥用于解密消息,这使得非对称加密更加安全,因为即使公钥被泄露,也无法破解密文。 常见的非对称加密:RSA
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
| public class RSA { public static final String KEY_ALGORITHM = "RSA"; private static final String PUBLIC_KEY = "RSAPublicKey"; private static final String PRIVATE_KEY = "RSAPrivateKey"; // 1024 bits 的 RSA 密钥对,最大加密明文大小 private static final int MAX_ENCRYPT_BLOCK = 117; // 1024 bits 的 RSA 密钥对,最大解密密文大小 private static final int MAX_DECRYPT_BLOCK = 128; // 生成密钥对 public static Map<String, Object> initKey(int keysize) throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); // 设置密钥对的 bit 数,越大越安全 keyPairGen.initialize(keysize); KeyPair keyPair = keyPairGen.generateKeyPair(); // 获取公钥 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 获取私钥 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); Map<String, Object> keyMap = new HashMap<>(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } // 获取公钥字符串 public static String getPublicKeyStr(Map<String, Object> keyMap) { // 获得 map 中的公钥对象,转为 key 对象 Key key = (Key) keyMap.get(PUBLIC_KEY); // 编码返回字符串 return encryptBASE64(key.getEncoded()); } // 获取私钥字符串 public static String getPrivateKeyStr(Map<String, Object> keyMap) { // 获得 map 中的私钥对象,转为 key 对象 Key key = (Key) keyMap.get(PRIVATE_KEY); // 编码返回字符串 return encryptBASE64(key.getEncoded()); } // 获取公钥 public static PublicKey getPublicKey(String publicKeyString) throws NoSuchAlgorithmException, InvalidKeySpecException { byte[] publicKeyByte = Base64.getDecoder().decode(publicKeyString); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyByte); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); return keyFactory.generatePublic(keySpec); } // 获取私钥 public static PrivateKey getPrivateKey(String privateKeyString) throws Exception { byte[] privateKeyByte = Base64.getDecoder().decode(privateKeyString); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyByte); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); return keyFactory.generatePrivate(keySpec); } /** * BASE64 编码返回加密字符串 * * @param key 需要编码的字节数组 * @return 编码后的字符串 */ public static String encryptBASE64(byte[] key) { return new String(Base64.getEncoder().encode(key)); } /** * BASE64 解码,返回字节数组 * * @param key 待解码的字符串 * @return 解码后的字节数组 */ public static byte[] decryptBASE64(String key) { return Base64.getDecoder().decode(key); } /** * 公钥加密 * * @param text 待加密的明文字符串 * @param publicKeyStr 公钥 * @return 加密后的密文 */ public static String encrypt1(String text, String publicKeyStr) { try { System.out.println("明文字符串为:"+text); Cipher cipher = Cipher.getInstance(KEY_ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, getPublicKey(publicKeyStr)); byte[] tempBytes = cipher.doFinal(text.getBytes("UTF-8")); return Base64.getEncoder().encodeToString(tempBytes); } catch (Exception e) { throw new RuntimeException("加密字符串[" + text + "]时遇到异常", e); } } /** * 私钥解密 * * @param secretText 待解密的密文字符串 * @param privateKeyStr 私钥 * @return 解密后的明文 */ public static String decrypt1(String secretText, String privateKeyStr) { try { // 生成私钥 Cipher cipher = Cipher.getInstance(KEY_ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, getPrivateKey(privateKeyStr)); // 密文解码 byte[] secretTextDecoded = Base64.getDecoder().decode(secretText.getBytes("UTF-8")); byte[] tempBytes = cipher.doFinal(secretTextDecoded); return new String(tempBytes); } catch (Exception e) { throw new RuntimeException("解密字符串[" + secretText + "]时遇到异常", e); } } public static void main(String[] args) throws Exception { Map<String, Object> keyMap; String cipherText; // 原始明文 String content = "吾爱破解论坛"; // 生成密钥对 keyMap = initKey(1024); String publicKey = getPublicKeyStr(keyMap); System.out.println("公钥:"+publicKey); String privateKey = getPrivateKeyStr(keyMap); System.out.println("私钥:"+privateKey); // 加密 cipherText = encrypt1(content, publicKey); System.out.println("加密后的密文:"+cipherText); // 解密 String plainText = decrypt1(cipherText, privateKey); System.out.println("解密后明文:"+plainText); } }
|
C语言实现
RC4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| #include <stdio.h> #include <string.h>
void rc4(const unsigned char *key, const unsigned char *input, unsigned char *output, int length) { int S[256], K[256]; for (int i = 0; i < 256; i++) { S[i] = i; K[i] = key[i % strlen((const char *)key)]; }
int j = 0; for (int i = 0; i < 256; i++) { j = (j + S[i] + K[i]) % 256; int temp = S[i]; S[i] = S[j]; S[j] = temp; }
int i = 0, k = 0; for (int n = 0; n < length; n++) { i = (i + 1) % 256; k = (k + S[i]) % 256; int temp = S[i]; S[i] = S[k]; S[k] = temp; output[n] = input[n] ^ S[(S[i] + S[k]) % 256]; } }
int main() { const unsigned char key[] = "1234567890abcdef"; const unsigned char input[] = "Hello, World!"; unsigned char output[sizeof(input)]; rc4(key, input, output, sizeof(input) - 1); printf("Encrypted: "); for (int i = 0; i < sizeof(input) - 1; i++) { printf("%02x", output[i]); } printf("\n");
unsigned char decrypted[sizeof(input)]; rc4(key, output, decrypted, sizeof(input) - 1); printf("Decrypted: %s\n", decrypted);
return 0; }
|
编码
Base64
一种用64个字符表示任意二进制数据的方法,是一种编码,并非加密字符编码,由 A-Z a-z 0-9 + / 和补充字符 “=” 组成,Base64编码后的字符数是4的倍数(不足会补”=”)
逻辑:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import java.util.Base64;
public class Base64Example { public static void main(String[] args) { String text = "吾爱破解论坛"; String encodedString = Base64.getEncoder().encodeToString(text.getBytes()); System.out.println("Encoded string: " + encodedString); byte[] decodedBytes = Base64.getDecoder().decode(encodedString); String decodedString = new String(decodedBytes); System.out.println("Decoded string: " + decodedString); } }
|
Hex编码
逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public static String stringToHex(String input) { StringBuilder output = new StringBuilder(); byte[] bytes = input.getBytes(StandardCharsets.UTF_8); for (byte b : bytes) { output.append(String.format("%02X", b)); } return output.toString(); }
public static String hexToString(String input) { byte[] bytes = new byte[input.length() / 2]; for (int i = 0; i < input.length(); i += 2) { bytes[i / 2] = (byte) Integer.parseInt(input.substring(i, i + 2), 16); } return new String(bytes, StandardCharsets.UTF_8); }
|
Unicode编码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public static String stringToUnicode(String input) { StringBuilder output = new StringBuilder(); for (int i = 0; i < input.length(); i++) { output.append(String.format("\\u%04X", (int) input.charAt(i))); } return output.toString(); }
public static String unicodeToString(String input) { StringBuilder output = new StringBuilder(); for (int i = 0; i < input.length(); i += 6) { String str = input.substring(i + 2, i + 6); output.append((char) Integer.parseInt(str, 16)); } return output.toString(); }
|
Byte数组
1 2 3 4 5 6 7 8 9 10 11 12 13
| public static void main(String[] args) { String originalInput = "吾爱破解论坛"; byte[] bytes = originalInput.getBytes(); System.out.println(Arrays.toString(bytes)); byte[] byteArray = new byte[]{-27,-112,-66,-25,-120,-79,-25,-96,-76,-24,-89,-93,-24,-82,-70,-27,-99,-101}; String str = new String(byteArray); System.out.println(str); }
|