java中常见加密

1.隐藏字节

  在逆向时,搜索关键词有可能搜索不到,原因有可能是字符串变成了字节,如下所示,4种方法都是声明了一个字符串叫武沛齐,但搜索时只有第一种方法能搜索到。

  当逆向时出现了第三和第四种声明的字符串,在python中还原步骤如下:

    --将每个字节数改为正值(负数的要+256)--->bytearray--->字符串

 

image

2.UUID

  在逆向时,出现uuid。如下所示,定义了UUID.randomUUID().toString()  这是产生一个随机的uuid并转成字符串。

image

  需要在python中实现时,如下所示:

image

 3.随机数

  如下图所示:v4变量是获取了一个随机字符串

      ---80代表随机生成80位二进制,二进制数8位代表一个字节,  共产生10个字节,一个字节的二进制数如:01001101

      ---16代表是16进制的字符串,一个字节转16进制长度为2,10个字节产生字符串长度20个

image

  在python 3.9中实现如下图所示,hex是代表转成16进制,最终res变量获取到了字符串长度20个,在python中16进制多了ox开头,所以通过切片的方法移除ox,关键代码hex(item)[2:]

image

   重点,应该这样写 ele=hex(item)[2:].rjust(2,"0")   原因是16进制有可能只有一个长度,需要在前面补0, rjust(2,"0") 表示产生2个长度,不够就在左侧补0

  下面是python3.9以下的实现方法

image

4.时间戳

   如下图所示:得到毫秒的时间戳转为字符串

image

   在python中,如下所示:

import  time
#秒级的时间戳
v1=str(int(time.time()))
#毫秒的时间戳
v1=str(int(time.time()*1000))

5.md5与SHA-256加密

  MD5是一种哈希函数,用于将任意长度的数据映射为固定长度的哈希值

  MD5加盐(Salting)是在密码哈希过程中增加一个随机字符串(称为盐),然后将盐与密码组合后再进行哈希。这样做的目的是确保即使两个用户有相同的密码,也会因为盐的不同而产生不同的哈希值。加盐可以有效防止彩虹表攻击。

  python中md5加盐示例如下(盐+密码):

import hashlib
import os

def hash_password(password):
    # 生成8字节的盐(通常足够)
    salt = os.urandom(8)
    # 将盐和密码组合(这里使用简单拼接)
    salted_password = password.encode('utf-8') + salt
    # 计算哈希值
    hash_obj = hashlib.md5(salted_password)
    # 返回盐和哈希值的十六进制表示(存储时两者都需要)
    return salt, hash_obj.hexdigest()

password = "my_password"
salt, hashed = hash_password(password)
print(f"Salt: {salt.hex()}")
print(f"Hash: {hashed}")


def verify_password(password, salt, stored_hash):
    # 将输入的密码与存储的f组合
    salted_password = password.encode('utf-8') + salt
    hash_obj = hashlib.md5(salted_password)
    computed_hash = hash_obj.hexdigest()
    # 比较计算出的哈希值和存储的哈希值
    return computed_hash == stored_hash

# 验证
print(verify_password("my_password", salt, hashed))  # True
print(verify_password("wrong_password", salt, hashed))  # False

  python中不加盐,如下图所示(只有密码'xxxxx'.encode('utf-8')),

image

  在Java中,我们可以使用java.security.MessageDigest进行MD5哈希,使用SecureRandom生成随机盐md5的加密,如下图所示(盐+密码):

  --需要注意:如果没有加try-catch ,在MessageDigest.getInstance 处IDE会检测到错误

  /**
     * 生成MD5加盐哈希
     * 
     * @param password 原始密码
     * @return 包含哈希值和盐的字符串数组 [哈希值, 盐]
     */
    public static String[] md5WithSalt(String password) {
        try {
            // 生成随机盐
            SecureRandom random = new SecureRandom();
            byte[] salt = new byte[16];
            random.nextBytes(salt);
            
            // 创建MD5消息摘要实例
            MessageDigest md = MessageDigest.getInstance("MD5");
            
            // 添加盐到密码
            md.update(salt);
            byte[] hashedPassword = md.digest(password.getBytes("UTF-8"));
            
            // 转换为十六进制字符串
            String hexHash = HexFormat.of().formatHex(hashedPassword);
            String hexSalt = HexFormat.of().formatHex(salt);
            
            return new String[]{hexHash, hexSalt};
        } catch (Exception e) {
            throw new RuntimeException("Error hashing password", e);
        }
    }
    

  java中不加盐,如下图所示(只有密码'str'.getBytes('UTF-8')),

image

    ---java中SHA-256加密代码与MD5的一样,区别在于MessageDigest.getInstance("SHA-256")

    ---python中SHA-256加密代码与MD5的一样,区别在于hashlib.sha256()

    --下面是B站中反逆向代码,使用了SHA-256,如果arg2不为空相当于加盐,g.H变为16进制(Hex)

image

6.AES加密

   对属于对称加密,key和iv(初始化向量)都是非常重要的参数

   key(密钥)的作用:用于加密和解密数据。在对称加密算法中,加密和解密使用相同的密钥,因此,密钥必须保密.

   iv(初始化向量)的作用:用于增强加密的强度。iv不需要保密,但应该每次加密都随机生成,以保证同样的明文每次加密产生的密文不同,从而增加安全性。

  key和iv都是字符串。AES要求密钥的长度为16字节(128位)、24字节(192位)或32字节(256位)。而CBC模式要求iv的长度必须为16字节(128位)

      -- key& iv  明文加密  【app端】 

      --key & iv 解密 【API】

  情况A:请求体密文(抓包乱码)

  情况B:sign, AES加密+base64编码

  以下是java的实现代码:  

public static  byte[] Encrypt() throws  Exception {
        String data = "自动化";
        //key的取值选项: 128位(16字节)、192位(24字节)或256位(32字节), 一个字节8位
        //这里定义16字节
        String key = "ThisIsA16ByteKey";

        //对于AES-CBC模式,必须是16字节(128位), 随机生成IV (16字节)安全性更强
        byte[] ivBytes = new byte[16];
        SecureRandom random = new SecureRandom();
        random.nextBytes(ivBytes);

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        byte[] raw = key.getBytes(StandardCharsets.UTF_8);
        SecretKeySpec sky = new SecretKeySpec(raw, "AES");
        IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
        cipher.init(Cipher.ENCRYPT_MODE, sky, ivSpec);
        byte[] encrypted = cipher.doFinal(data.getBytes());
        System.out.println("加密后的字节数组:" + Arrays.toString(encrypted));
        System.out.println("Base64编码的加密结果:" + Base64.getEncoder().encodeToString(encrypted));
        return encrypted;
    }

  输出的结果如下:


加密后的字节数组:[-72, -66, 94, -127, -51, -124, 61, 4, -76, 64, 127, -77, -123, 117, 79, -103]
Base64编码的加密结果:uL5egc2EPQS0QH+zhXVPmQ==

  下面也是逆向后,一段Aes加密代码返回byte数组,arg2是key,  arg3是iv,

           arg4是要加密的内容转为了byte数组,要知道传进来的byte数组转为明文是什么。

           v0.init中第一个参数是1 表示:Cipher.ENCRYPT_MODE

image

 7.常见的base64编码

  

/*
        base64Helper.Encoder("自动化")
        output:6Ieq5Yqo5YyW
    */
    public  static String Encoder(String name)
    {
        Base64.Encoder encoder = Base64.getEncoder();
        String base64 = encoder.encodeToString(name.getBytes());
        System.out.println(base64);
        return   base64;
    }

    /*
        base64Helper.Decoder("6Ieq5Yqo5YyW")
        output:自动化
    */
    public  static void Decoder(String base64Str)
    {
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] origin= decoder.decode(base64Str);
        String name = new String(origin);
        System.out.println(name);
    }

  下面是python的实现

image

 

posted on 2025-09-15 12:32  花阴偷移  阅读(2)  评论(0)    收藏  举报

导航