[NepCTF 2023] crypto 复现

 这个赛很不理想,啥都不会。

拿了WP看了几个题,记录一下

random_RSA

这题不会是正常情况,我认为。对于论文题,不知道就是不知道,基本没有可能自己去完成论文。

题目不长,只有两个菜单,共可交互8次,输入1时会随机数生成p,q,d(生成随机数左移32位再取next_prime)然后给出e(e对应的phi是(p^2-1)*(q^2-1)),输入2时会再生成p,q用e=0x10001生成c

from gmpy2 import next_prime, invert as inverse_mod
from Crypto.Cipher import PKCS1_v1_5
from Crypto.PublicKey import RSA
from random import getrandbits
from math import lcm
from sys import exit

global_bits = 1024

BANNER = rb"""
.--------.--------.--------.--------.--------.--------.--------.--------.--------.--------.--------.
| N.--.  | E.--.  | P.--.  | C.--.  | T.--.  | F.--.  | H.--.  | A.--.  | P.--.  | P.--.  | Y.--.  |
|  :/\:  |  (\/)  |  :():  |  :/\:  |  :/\:  |  :/\:  |  (\/)  |  :():  |  :/\:  |  :/\:  |  (\/)  |
|  :\/:  |  :\/:  |  ()()  |  (__)  |  :\/:  |  (__)  |  :\/:  |  ()()  |  :\/:  |  :\/:  |  :\/:  |
|  '--'n |  '--'e |  '--'p |  '--'c | '--'t  |  '--'f |  '--'h |  '--'a |  '--'p |  '--'p |  '--'y |
`--------`--------`--------`--------'--------`--------`--------`--------`--------`--------`--------`
"""


def generate_prime(bits: int):
    p = (getrandbits(bits - 32) << 32)
    return next_prime(p)


def generate_private_key(bits: int):
    p, q = generate_prime(bits), generate_prime(bits)
    n, phi = p * q, lcm(p-1, q - 1)

    d = inverse_mod(0x10001, phi)
    privateKey = RSA.construct((int(n), int(0x10001), int(d), int(p), int(q)))
    return privateKey, p > q


if __name__ == "__main__":
    print(BANNER.decode())
    print("Welcome to the world of random RSA.")
    print("Please make your choice.")
    for _ in range(8):
        choice = input()

        if choice == '1':
            p, q = generate_prime(global_bits), generate_prime(global_bits)
            N = p*q
            d = generate_prime(global_bits-32)
            e = inverse_mod(d, (p * p - 1) * (q * q - 1))
            print(f"{int(N)}")
            print(f"{int(e)}")

        elif choice == '2':
            privateKey, signal = generate_private_key(global_bits)
            Cipher = PKCS1_v1_5.new(privateKey)
            c = (Cipher.encrypt(flag.encode()))
            print(c)
            exit()

        else:
            exit()

这里菜单2没有给出p,q显然是通过前边的随机数预测。

1,ed = 1 + k(p^2-1)(q^2-1)如果分解的问题,这个关于论文也就不解释了,解释不清,解法就是通过连分式分解

\frac{e}{N^{2}-\frac{9}{4}N + 1}

结果是k,d,所以先交换取7个1和1个2然后回来慢慢处理,得到p,q,d的数组。

from gmpy2 import iroot 

def contfrac_attack(e,n):
    convergents = continued_fraction(ZZ(e) / ZZ(int(n^2 -9/4*n +1))).convergents()
    for c in convergents:
        k = c.numerator()
        d = c.denominator()
        if pow(pow(2,int(e),int(n)),int(d),n) == 2:
            phi = (e*d - 1)//k
            p_add_q = iroot(n^2+1 -phi +2*n,2)[0]
            p_sub_q = iroot(n^2+1 -phi -2*n,2)[0]
            p = (p_add_q + p_sub_q)//2
            q = n//p 
            #if p<q:
            #    p,q = q,p 
            #print('[',p,',',q,',',d,'],')
            return p,q,d


N = [data[i] for i in range(0,len(data),2)]
E = [data[i+1] for i in range(0,len(data),2)]
pqd = []
for e,n in zip(E,N):
    p,q,d = contfrac_attack(e,n)
    pqd.append([p,q,d])

2,通过MT19937来恢复random求p,q

由于给出的p,q是什么顺序未知这里需要一个爆破2^7很小

from Crypto.Cipher import PKCS1_v1_5
from Crypto.PublicKey import RSA
from extend_mt19937_predictor import ExtendMT19937Predictor
from gmpy2 import invert,next_prime
from math import lcm 
import itertools 

bits = 1024
e = 0x10001

def gen1(bits: int):
    p = (getrandbits(bits - 32) << 32)
    return next_prime(p)

def gen2(bits: int):
    p = (predictor.predict_getrandbits(bits - 32) << 32)
    return next_prime(p)


for o in itertools.product([0,1], repeat=7):
    try:
        predictor = ExtendMT19937Predictor()
        for i,v in enumerate(pqd):
            #print(v)
            predictor.setrandbits(v[o[i]]>>32, 992) #31+31+30
            predictor.setrandbits(v[1-o[i]]>>32, 992)
            predictor.setrandbits(v[2]>>32, 960)
    except:
        continue
    
    p,q = gen2(bits),gen2(bits)
    n = p*q
    phi = lcm(p-1,q-1)
    d = invert(e, phi)
    
    privateKey = RSA.construct((int(n), int(e), int(d), int(p), int(q)))
    Cipher = PKCS1_v1_5.new(privateKey)
    try:
        flag = (Cipher.decrypt(c,'\x00'))
        print(flag)
    except:
        continue 

#b'NepCTF{c4e4356067fb3bedc53dde7af59beb1c}'

对于用PKCS1打包的RSA还要用它来解,并且题上用咱就用咱lcm(p-1,q-1)和(p-1)*(q-1)不相等。

MT19937在填入数据的时候,如果重复部分有误会报错,这时候应该就是p,q的顺序不正确了。这题一共得到644组32位随机数有20组,比624多20组这样,在这里通过的后边都正确,但是有几组在后边生成时并未用到,所以有多组相同的解

 recover

这题作一半卡了,脑子有点晕了,没看到提示flag的格式。

from math import ceil
from hashlib import md5

from Crypto.Util.number import *

#from secret import key, flag
key = b'bfaxctvpacpfxsrljavvvmsi'
flag = b'flag{flag_is_the_readable_key_whose_md5_starts_with_3fe04}'

def MD5(x): return md5(x).hexdigest()


assert (len(flag) == 58)
assert (len(key) == 24)

P = [[0, 2, 3, 4, 5, 6],
     [1, 4],
     [0, 3],
     [0, 3, 4, 5],
     [0, 1, 2, 3, 4, 7],
     [2, 3, 4, 5, 6],
     [0, 1, 2, 3],
     [1, 2, 3, 4, 5, 7],
     [8, 12, 13, 14],
     [8, 11, 12, 13, 15],
     [9, 12, 15],
     [11, 13, 15],
     [8, 9, 10, 12, 13, 15],
     [8, 9],
     [11, 13, 14],
     [10],
     [16, 19, 20],
     [16, 18, 19, 20, 21],
     [16, 17, 18, 19],
     [17, 18, 20, 22, 23],
     [17, 19, 23],
     [17, 18, 20, 21, 23],
     [16, 18, 20, 21, 22, 23],
     [16, 17, 18, 20, 21, 22, 23],
     [25, 26, 29, 31],
     [25, 26],
     [26, 28, 30],
     [27, 28, 29, 30, 31],
     [25, 29],
     [25, 26, 30, 31],
     [28, 29, 30, 31],
     [24, 26, 29, 31],
     [35, 36, 39],
     [33, 35, 38],
     [33, 35, 37, 39],
     [32, 33, 34, 35, 37, 38],
     [32, 33, 34, 35, 37, 39],
     [35, 38],
     [33, 34, 38, 39],
     [33, 34, 39],
     [41, 42, 43, 44, 47],
     [40, 41, 42, 45, 47],
     [41, 42, 45, 47],
     [40, 43, 44, 46],
     [41, 46, 47],
     [41, 42, 43, 44, 46, 47],
     [41, 42, 44, 45],
     [40, 41, 42, 45, 46],
     [48, 50, 51, 52, 53, 54, 55],
     [48, 49, 50, 52, 53, 54, 55],
     [49, 55],
     [48, 49, 50, 51, 52, 54],
     [52, 53],
     [48, 49, 53, 54, 55],
     [48, 49, 52, 55],
     [48, 49, 51, 52, 55],
     [58, 59],
     [56, 61, 63],
     [57, 63],
     [56, 59, 60],
     [61, 63],
     [57, 58, 61, 62, 63],
     [57, 58],
     [60, 62]]


def enc(v, keys, le):
    t = v
    for i in keys:
        q = []
        for j in P:
            tmp = 0
            for k in j:
                tmp ^= t[k]
            q.append(tmp)
        t = [int(q[j]) ^ int(i[j]) for j in range(le)]
    return t


keys = []
for i in range(len(key)//8):
    l = bytes_to_long(key[i*8:i*8+8])
    m = bin(l)[2:].zfill(8*8)
    keys.append([int(i) for i in m])

fb = bin(bytes_to_long(flag))[2:].zfill(ceil(len(flag)/8)*8*8)

ciphertext = ""
for i in range(0, len(fb), 64):
    t = enc([int(j) for j in fb[i:i+64]], keys, 64)
    ciphertext += "".join([str(j) for j in t])

print(ciphertext)
cipher = '11101100100000110101100101100001100111011100100111000000010110000110011011000100110101110111010000100100001100010011001100010100101000110001011101000000100010101000000110000110011110001101110110110111000000100010011011011011101011101000000000100010000101001110100101011000001110010000000000100110001101110011111010001100101101111010101111101110100110101010011010011010101110100001001101100110010000010000011100100101111010010000011001000110000100110111100010101011000100100111010000101010110110001010110101111111'
print(cipher)

这里P有64组数据,很显然每8个一组,可以看成m*A=c的运算,由于key有24字节,这个运算共进行了3次,也就是对一个字符 ((m*A+key1)*A + key2)*A+key3对一个字节这样加密以后,key可能是多组的。

由于给出了flag的格式flag{...}58个字符前补0成64个分8*8,这样按列每组都给了一两个明文,其它明文提示是小字字母(想错了),所以很容易爆破出一组key来。用这个key求出其它字符。每次改一下idx就能求出一列数据,后来有几组出不来,发现不只是小写字母。说是爆破其实量极小,秒出的那种。

idx = 4
v0 = [0,0,0,0,0,0,ord('f'),ord('l')]
tp = P[idx*8: idx*8+8]
tP = [[i-idx*8 for i in t] for t in tp]
print(tP)
for v1 in 'l':
    for v in 'h':
        vs = get_v(v0[idx],ord(v1), ord(v))
        cs = [ciphers[idx], ciphers[idx + 8], ciphers[idx + 16]]
        key0 = get_key(vs,cs, tP)
        if key0 == False:
            continue
        print('Try:', idx, v1, v)
        for i in range(8):
            ok = False
            for v2 in tab:
                t = enc([int(i) for i in bin(ord(v2))[2:].zfill(8)], key0, 8, tP)
                if all(int(ciphers[idx + i*8][j])==t[j]  for j in range(8)):
                    ok = True 
                    print(i,v2)
            if not ok:
                break
        else:
            print(f'key {idx}', key0)
   

'''
000000fl
ag{flag_
is_the_r
eadable_
key_whos
e_md5_st
arts_wit
h_3fe04}
'''
#flag{flag_is_the_readable_key_whose_md5_starts_with_3fe04}

然后第2步卡了,这里说flag是可读的且md5头是这个。这里一时没想到flag的格式,所以每组可能的key有100多组,8组就有巨多,就没法弄了。后来看WP,原来提示的那一句在这里用。如果真正的key也是有flag{...}格式的话,那的提示的有6组,爆破就没几个了。

每求出每组key的组合

def get_int(aa):
    return [int(''.join(map(str, a)),2)for a in aa]
    
def get_list(k1,k2,k3):  
    return [[int(i) for i in bin(ord(a))[2:].zfill(8)] for a in [k1,k2,k3]]    
    
def get_key2(vs,cs,tP):
    keys = [BitVec(f'key_{i}',1) for i in range(24)]
    key_arr = [keys[i:i+8] for i in range(0,24,8)]
    print(vs)
    print(cs)
    print(tP)
    s = Solver()
    s.add(keys[0] == 0)
    s.add(keys[8] == 0)
    s.add(keys[16] == 0)
    for v,c in zip(vs,cs):
        t = enc(v, key_arr,8, tP)
        for i,tk in enumerate(t):
            s.add(tk == int(c[i]))
    
    allkey = []
    while s.check() == sat:
        d = s.model()
        rkey = [d[keys[i]].as_long() for i in range(24)]
        rkey_arr = [rkey[i:i+8] for i in range(0,24,8)]
        #print(rkey_arr)
        tmp = get_int(rkey_arr)
        if all(0x20<=v<0x7f for v in tmp):
            allkey.append(tmp)
            
        condition = []
        for i in range(24):
           condition.append(keys[i] != rkey[i])
        s.add(Or(condition))
        
    return allkey 

flag = b'flag{flag_is_the_readable_key_whose_md5_starts_with_3fe04}'
vs = [0]*6 + [v for v in flag]
#print(vs)

tab = string.ascii_lowercase 
tabs = list('flag{') + [tab]*18 + ['}']
print(tabs)
for idx in range(8):
    tp = P[idx*8: idx*8+8]
    tP = [[i-idx*8 for i in t] for t in tp]
    tv = [[int(i) for i in bin(vs[j*8 + idx])[2:].zfill(8)] for j in range(8)]
    tc = [ciphers[idx + j*8] for j in range(8)]
    allkey = []
    for k1 in tabs[idx]:
        for k2 in tabs[idx+8]:
            for k3 in tabs[idx+16]:
                key0 = get_list(k1,k2,k3)
                for i,v2 in enumerate([vs[i*8+idx] for i in range(8)]): 
                    t = enc([int(i) for i in bin(v2)[2:].zfill(8)],key0, 8, tP)
                    if int(ciphers[idx + i*8],2) == int(''.join(map(str,t)),2):
                        allkey.append(k1+k2+k3)
    
    print(list(set(allkey)))  

然后对这些爆破,然后眼工找到一组能读的。

k = [
['fcw', 'fdo', 'fef'],
['lnd', 'lxn', 'lev'],
['asz', 'are', 'aqi', 'apv'],
['gan', 'gkj', 'gnf', 'gtr', 'gdb'],
['{ok', '{qy', '{bx'],
['cbk', 'ahm', 'ygt', 'joe', 'lio', 'tir', 'arr', 'jxc', 'ypr', 'vnm', 'yjm', 'ldv', 'agi', 'cor', 'nat', 'hre', 'gng', 'ppe', 'vct', 'esg', 'nvr', 'rba', 'lsp', 'pgc', 'tsm', 'tfv', 'vyk', 'tqp', 'vvo', 'pjz', 'vai', 'ajp', 'cum', 'rug', 'lqm', 'nci', 'nyv', 'jmx', 'apo', 'yhp', 'vlp', 'juz', 'aet', 'rwz', 'eix', 'hpx', 'hec', 'tko', 'nlm', 'jwg', 'hjg', 'rzc', 'cxt', 'cwp', 'tdk', 'gve', 'rox', 'eke', 'gya', 'eqz', 'cmo', 'yei', 'phg', 'vtr', 'yro', 'czi', 'nnp', 'hhz', 'rme', 'gac', 'eda', 'lkr', 'glz', 'lfk', 'gtx', 'nto', 'prx'],
['kjy', 'hqr', 'qpb', 'tyf', 'vrs', 'tsi', 'cht', 'mxv', 'wbm', 'pfd', 'lhh', 'qzm', 'gqn', 'wdu', 'osc', 'xbq', 'aov', 'ept', 'fap', 'mry', 'yro', 'oyl', 'pjs', 'bre', 'cnl', 'dfr', 'raf', 'tuq', 'cdc', 'nir', 'qvz', 'ytw', 'whb', 'rmq', 'evl', 'sqx', 'uix', 'ikc', 'wnz', 'fmg', 'ueo', 'dje', 'aey', 'lnp', 'xnf', 'zes', 'fgh', 'ain', 'igt', 'ucw', 'bxj', 'nee', 'hwj', 'lbg', 'mta', 'zid', 'jph', 'aca', 'noj', 'ial', 'vtk', 'rki', 'kfn', 'zck', 'plk', 'jzg', 'xdi', 'kla', 'jvp', 'gwv'],
['zr}', 'pf}', 'xw}', 'rc}']]

from hashlib import md5

v =[0]*8
for v[0] in k[0]:
  for v[1] in k[1]:
    for v[2] in k[2]:
      for v[3] in k[3]:
        for v[4] in k[4]:
          for v[5] in k[5]:
            for v[6] in k[6]:
              for v[7] in k[7]:
                key = ''.join(''.join(r[i] for r in v) for i in range(3))
                m = md5(key.encode()).hexdigest()
                if m.startswith('3fe04'):
                    print(key, m)

#flag{hardertorecoverkey}
'''
flag{aapcnsabjcfwdznxpa} 3fe042d564d4e19a99c18038e95a4923
flag{npxcxsnovlwwnzfkrk} 3fe044e1e71f56918db24bc143cbdd02
flag{chrcxsnqmwcwnzfyoj} 3fe045110e1506d003ae582f22ce3d6c
flag{gsrcxpnbtqcwnvfxxx} 3fe044fcc37311bc71e76987e341ee16
flag{ycrcxptopncwnvrkrl} 3fe049dcd66d48a19f824ed9dfd51ae2
flag{vxrceraocncwvenktf} 3fe0477ae63f44db4e5657ae34b71f8e
flag{yrpcepkbrkfwvvjxoi} 3fe040c7d8ff041d0784e93b952f206a
flag{gvxdxsdqytwonzbyak} 3fe043b101bbbec84b04027f4872e6a5
flag{rwzdxpnobbronvfkam} 3fe04ea7bc9169f9565730a5786a767b
flag{hardertorecoverkey} 3fe0442d2939da2767c07fe4b735a917
flag{gczenstoldrfdzrkzc} 3fe04b78470cb999ecce16590b5a2a04
flag{nfpexsnqnmffnzfypg} 3fe04a6cce75c141462498c92e7517bf
flag{afpeesdbjgffvzbxph} 3fe04500376029ba4432e8af5d79b00b
'''           

后边两个恩格码机的题,第1个是基于明文不出现在密文中,比如明文第5位是A则密文中第5位一定不是A。

第二个基于某个论文。跳过。

secureAgg

这个题目很长,如果能有时间认识读题就能答。

AggServer.py

from Crypto.Util.number import *
from User import User

class AggServer:

    def __init__(self,mbits):
        self.N=8
        self.g=2
        self.p=0x9f785dd75d97d7dea66a89a038e7c880b962e526fa9d0f14639de8d82b953fbf0e01739495df3d5fdb189aa079c70e9cc49c7390c2fd3166d91fe8b511f918a7
        self.mbits=mbits
        self.users=[ User(mbits,i) for i in range(self.N)]
        self.M=getPrime(mbits+self.N.bit_length()+1)
        self.params=(self.g,self.p)
    
    def genKeys(self):
        for u in self.users:
            u.genKey(self.params)
        for u in self.users:
            u.agree(self.users,self.params[1])
    
    def get_enc_list(self):  #泄露
        enc_list=[]
        for u in self.users:
            enc_data=u.get_enc_data(self.M)
            enc_list.append(enc_data)
        return enc_list
    
    def aggregate(self):   #生成key
        self.key=sum([ u.data for u in self.users])%self.M
        return self.key
    
    def update(self):
        for u in self.users:
            u.update_data(self.key)

    def system_info(self):
        info = ""
        info += "System params: \n"
        info += f"g={self.params[0]}\np={self.params[1]}\nM={self.M}\n"
        info += "User pubkeys: \n"
        info += f"pubkeys={str([ u.pub for u in self.users])}\n"
        return info

chall.py

# !/usr/bin/env python
from Crypto.Util.number import *
from hashlib import sha256
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from base64 import b64encode
from FLAG import flag
from AggServer import AggServer
import socketserver
import os, sys, random
import signal, string

ROUNDS=20
BANNER=br'''
            Welcome to my Secure Aggregation System.
    If you can pass my 20 rounds of agg testing, I'll give you flag~
                        Have fun! 
'''


class Task(socketserver.BaseRequestHandler):
    def _recvall(self):
        BUFF_SIZE = 2048
        data = b''
        while True:
            part = self.request.recv(BUFF_SIZE)
            data += part
            if len(part) < BUFF_SIZE:
                break
        return data.strip()

    def send(self, msg, newline=True):
        try:
            if newline:
                msg += b'\n'
            self.request.sendall(msg)
        except:
            pass

    def recv(self, prompt=b'> '):
        self.send(prompt, newline=False)
        return self._recvall()

    def close(self):
        self.request.close()

    def handle(self):
        signal.alarm(180)

        self.send(BANNER)
        self.send(b"Generating parameters...")
        agg=AggServer(114)
        agg.genKeys()
        self.send(agg.system_info().encode())

        try:
            for i in range(ROUNDS):
                self.send(f'#Round {i+1}'.encode())
                enc_list=agg.get_enc_list()
                self.send(f"enc_list={enc_list}".encode())
                key=agg.aggregate()
                message=''.join(random.sample(string.ascii_letters,16))
                aes_key=sha256(str(key).encode()).digest()[:16]
                aes=AES.new(aes_key,AES.MODE_CBC,iv=bytes(range(16)))
                enc=aes.encrypt(pad(message.encode(),16))
                self.send(f"enc={b64encode(enc)}".encode())
                inp=self.recv(b"input your message: ").decode()
                if inp==message:
                    self.send(b'Correct!')
                else:
                    self.send(b'Error!')
                    exit(0)
                agg.update()
            self.send(flag)
        except:
            self.send(b'wtf?')
        self.close()


class ThreadedServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass


class ForkedServer(socketserver.ForkingMixIn, socketserver.TCPServer):
    pass


if __name__ == "__main__":
    HOST, PORT = '0.0.0.0', 12345
    server = ForkedServer((HOST, PORT), Task)
    server.allow_reuse_address = True
    server.serve_forever()


usr.py

from Crypto.Util.number import *

class PRG:
    def __init__(self,seed):
        self.state=seed
        self.a=114514
        self.b=1919810
        self.kbits=seed.bit_length()
        self.bits=[]
    
    def gen(self):
        self.state=(self.a*self.state+self.b)&((1<<self.kbits)-1)
        bin_arr=list(map(int,bin(self.state)[2:].zfill(self.kbits)[::-1]))
        self.bits.extend(bin_arr)

    def randbits(self,n):
        while len(self.bits)<n:
            self.gen()
        output=self.bits[:n]
        self.bits=self.bits[n:]
        return int(''.join(map(str,output)),2)


class User:

    def __init__(self,mbits,id):
        self.mbits=mbits
        self.id=id
        self.data=getRandomNBitInteger(mbits)

    def genKey(self,params):
        g,p=params
        self.priv=getRandomRange(1,p)
        self.pub=pow(g,self.priv,p)

    def agree(self,users,p):
        self.agreement_keys={}
        for u in users:
            if u.id!=self.id:
                u_pub=u.pub
                k=pow(u_pub,self.priv,p)
                self.agreement_keys.update({u.id:k})
    
    def get_enc_data(self,M):
        enc=(114*self.data+514)%M
        for id,k in self.agreement_keys.items():
            if id>self.id:
                enc+=PRG(k).randbits(self.mbits)%M
            elif id<self.id:
                enc-=PRG(k).randbits(self.mbits)%M
        return enc
    
    def update_data(self, key):
        mask=(1<<self.mbits)-1
        noise=getRandomNBitInteger(16)
        self.data=(self.data ^ key ^ noise) & mask

chall.py给了一个交互的服务,如果正确20次就给flag

先成成Agg,然后每一轮都先给出 enc_list=agg.get_enc_list(),这个函数调用users

    def get_enc_list(self):  #泄露
        enc_list=[]
        for u in self.users:
            enc_data=u.get_enc_data(self.M)
            enc_list.append(enc_data)
        return enc_list

users里的加密是个非常小的LCG

    def get_enc_data(self,M):
        enc=(114*self.data+514)%M
        for id,k in self.agreement_keys.items():
            if id>self.id:
                enc+=PRG(k).randbits(self.mbits)%M
            elif id<self.id:
                enc-=PRG(k).randbits(self.mbits)%M
        return enc

显然,这里组出enc_data 求data只需要 (sum(enc_data)-514*8)*114^-1 % M,最后在有key的情况下求AES就行了。

最后一个关于DES的太长了,没看,说是很简单。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Node.js 中的 crypto 是一个内置模块,用于提供加密和解密功能。它支持各种加密算法和操作,包括哈希函数、对称加密和非对称加密。你可以使用 crypto 模块来实现数据的加密、解密、签名和验证等操作。 要使用 crypto 模块,你需要在你的代码中引入它,例如: ```javascript const crypto = require('crypto'); ``` 一些常见的 crypto 操作包括: 1. 哈希函数:crypto 模块提供了多个哈希函数,如 MD5、SHA-1、SHA-256 等。你可以使用这些函数对数据进行哈希处理,生成唯一的摘要。例如: ```javascript const hash = crypto.createHash('sha256'); hash.update('Hello, world!'); const digest = hash.digest('hex'); console.log(digest); // 输出生成的摘要 ``` 2. 对称加密:crypto 模块支持对称加密算法,如 AES、DES、3DES 等。你可以使用这些算法对数据进行加密和解密。例如: ```javascript const cipher = crypto.createCipher('aes192', 'password'); let encrypted = cipher.update('Hello, world!', 'utf8', 'hex'); encrypted += cipher.final('hex'); console.log(encrypted); // 输出加密后的数据 const decipher = crypto.createDecipher('aes192', 'password'); let decrypted = decipher.update(encrypted, 'hex', 'utf8'); decrypted += decipher.final('utf8'); console.log(decrypted); // 输出解密后的数据 ``` 3. 非对称加密:crypto 模块还支持非对称加密算法,如 RSA。你可以使用这些算法生成公钥和私钥,进行加密和解密。例如: ```javascript const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', { modulusLength: 4096, publicKeyEncoding: { type: 'spki', format: 'pem' }, privateKeyEncoding: { type: 'pkcs8', format: 'pem' } }); console.log(publicKey); // 输出生成的公钥 console.log(privateKey); // 输出生成的私钥 const encrypted = crypto.publicEncrypt(publicKey, Buffer.from('Hello, world!')); console.log(encrypted.toString('base64')); // 输出加密后的数据 const decrypted = crypto.privateDecrypt(privateKey, encrypted); console.log(decrypted.toString('utf8')); // 输出解密后的数据 ``` 这只是 crypto 模块的一小部分功能,你可以查阅 Node.js 文档以获取更详细的信息和使用方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值