AES加密解密long型id

本文介绍了一种使用Java实现的生成系统内唯一且防伪的订单号的方法,通过AES加密自增ID并结合Base58编码,确保了订单号的安全性和唯一性。

Java实现的一个生成系统内唯一且无法被伪造的订单号的工具,基本思路是对long型自增的id加密解密,加密算法是AES,需要结合其他encode/
decode方法。

AESUtil

加密解密的工具类

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class AESUtil {
    private static final byte[] SECRET_KEY = "7975922666f6eb02".getBytes(StandardCharsets.UTF_8);

    public static byte[] encrypt(byte[] plaintext) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        SecretKeySpec secretKeySpec = new SecretKeySpec(SECRET_KEY, "AES");
        // 算法/模式/补码方式
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
        return cipher.doFinal(plaintext);
    }

    public static byte[] decrypt(byte[] ciphertext) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
            SecretKeySpec secretKeySpec = new SecretKeySpec(SECRET_KEY, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            return cipher.doFinal(ciphertext);
    }

    public static byte[] encryptId(long id) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
        byte[] plaintext = new byte[8];
        for(int i = 0;i < 8; ++i) {
            plaintext[i] = (byte) ((id >> (7 - i) * 8) & 0xFF);
        }
        return encrypt(plaintext);
    }

    public static long decryptId(byte[] ciphertext) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
        long id = 0;
        byte[] plaintext = decrypt(ciphertext);
        for(int i = 0;i < 8; ++i) {
            id |= (long) (plaintext[i] & 0xFF) << (7 -i) * 8;
        }
        return id;
    }
}

加密后得到的是byte数组,需要结合encode工具,下面是一个Base58编码工具

Base58Util

import java.math.BigInteger;

public class Base58Util {
    private static final String ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
    private static final BigInteger BASE = BigInteger.valueOf(58L);

    public Base58Util() {
    }

    public static String encode(byte[] input) {
        BigInteger bi = new BigInteger(1, input);

        StringBuffer s;
        BigInteger mod;
        for(s = new StringBuffer(); bi.compareTo(BASE) >= 0; bi = bi.subtract(mod).divide(BASE)) {
            mod = bi.mod(BASE);
            s.insert(0, "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".charAt(mod.intValue()));
        }

        s.insert(0, "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".charAt(bi.intValue()));
        byte[] var7 = input;
        int var4 = input.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            byte anInput = var7[var5];
            if (anInput != 0) {
                break;
            }

            s.insert(0, "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".charAt(0));
        }

        return s.toString();
    }

    public static byte[] decode(String input) {
        byte[] bytes = decodeToBigInteger(input).toByteArray();
        boolean stripSignByte = bytes.length > 1 && bytes[0] == 0 && bytes[1] < 0;
        int leadingZeros = 0;

        for(int i = 0; input.charAt(i) == "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".charAt(0); ++i) {
            ++leadingZeros;
        }

        byte[] tmp = new byte[bytes.length - (stripSignByte ? 1 : 0) + leadingZeros];
        System.arraycopy(bytes, stripSignByte ? 1 : 0, tmp, leadingZeros, tmp.length - leadingZeros);
        return tmp;
    }

    public static BigInteger decodeToBigInteger(String input) {
        BigInteger bi = BigInteger.valueOf(0L);

        for(int i = input.length() - 1; i >= 0; --i) {
            int alphaIndex = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".indexOf(input.charAt(i));
            if (alphaIndex == -1) {
                throw new IllegalStateException("Illegal character " + input.charAt(i) + " at " + i);
            }

            bi = bi.add(BigInteger.valueOf((long)alphaIndex).multiply(BASE.pow(input.length() - 1 - i)));
        }

        return bi;
    }
}
### 使用AES加密和解密的CBC模式实现示例 以下是基于Python语言的一个完整的AES加密和解密实现例子,该方法支持CBC模式并兼容OpenSSL标准[^2]。 #### 加密过程 在加密过程中,需要初始化向量(IV),以及指定长度为16字节的秘密密钥。为了确保数据能够被正确填充到块大小,通常会使用PKCS#7填充方案。 ```python from Crypto.Cipher import AES import base64 import os def pad(s, block_size=16): """Pad the input string to a multiple of `block_size` bytes.""" padding_length = block_size - (len(s) % block_size) return s + chr(padding_length) * padding_length def encrypt(plaintext, key, iv): cipher = AES.new(key.encode(), AES.MODE_CBC, iv.encode()) padded_text = pad(plaintext).encode() encrypted_bytes = cipher.encrypt(padded_text) return base64.b64encode(encrypted_bytes).decode() key = 'mysecretpassword' # Must be either 16, 24 or 32 bytes long. iv = os.urandom(16).hex()[:16] # Initialization vector must also be 16 bytes. ciphertext = encrypt('This is my secret message.', key, iv) print(f"Ciphertext: {ciphertext}") ``` #### 解密过程 对于解密操作,则需先将Base64编码的数据转换回原始字节数组形式,并利用相同的密钥与初始向量来还原明文内容。注意,在此之前还需移除先前所加上的填充字符。 ```python def unpad(s): """Remove PKCS#7 padding from the given decrypted text.""" last_char = s[-1] if isinstance(last_char, int): # For Python 3 compatibility return s[:-last_char] else: return s[:-ord(last_char)] def decrypt(ciphertext_base64, key, iv): ciphertext_bytes = base64.b64decode(ciphertext_base64) cipher = AES.new(key.encode(), AES.MODE_CBC, iv.encode()) decrypted_padded = cipher.decrypt(ciphertext_bytes) return unpad(decrypted_padded.decode()) original_message = decrypt(ciphertext, key, iv) print(f"Decrypted Message: {original_message}") ``` 上述代码片段展示了如何通过PyCrypto库执行基本的AES CBC模式下的文件或字符串级别的加密与解密功能[^1]。此外还提供了另一种方式即遵循OpenSSL协议的标准处理流程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值