实现接口加密验签需要使用加密算法和数字签名算法。一般来说,加密算法用于加密请求参数,数字签名算法用于对请求参数进行签名,以确保请求参数的完整性和真实性。在Java中,可以使用Java加密扩展(Java Cryptography Extension,JCE)来实现加密和数字签名算法。
以下是一个基本的Java接口加密验签实现的示例代码,假设使用SHA256算法进行数字签名,AES算法进行对称加密,有效期为5分钟:
import java.util.Base64;
import java.util.Date;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class InterfaceEncryption {
private static final String AES_ALGORITHM = "AES";
private static final String SIGNATURE_ALGORITHM = "SHA256";
// 获取密钥
private static SecretKey generateAESKey() throws NoSuchAlgorithmException {
KeyGenerator keyGenerator = KeyGenerator.getInstance(AES_ALGORITHM);
keyGenerator.init(256);
return keyGenerator.generateKey();
}
// 对明文进行AES加密
private static byte[] aesEncrypt(byte[] plainText, SecretKey key) throws Exception {
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(plainText);
}
// 对密文进行AES解密
private static byte[] aesDecrypt(byte[] cipherText, SecretKey key) throws Exception {
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(cipherText);
}
// 对明文进行数字签名
private static byte[] generateSignature(byte[] plainText, SecretKey key) throws Exception {
MessageDigest digest = MessageDigest.getInstance(SIGNATURE_ALGORITHM);
digest.update(plainText);
return digest.digest(key.getEncoded());
}
// 验证数字签名是否有效
private static boolean verifySignature(byte[] plainText, byte[] signature, SecretKey key) throws Exception {
byte[] actualSignature = generateSignature(plainText, key);
return MessageDigest.isEqual(actualSignature, signature);
}
// 将密钥转化为Base64字符串
private static String keyToString(SecretKey key) {
return Base64.getEncoder().encodeToString(key.getEncoded());
}
// 对请求参数进行加密和数字签名
public static String encryptAndSign(String data) throws Exception {
SecretKey key = generateAESKey();
byte[] cipherText = aesEncrypt(data.getBytes(), key);
byte[] signature = generateSignature(cipherText, key);
String keyString = keyToString(key);
String cipherTextString = Base64.getEncoder().encodeToString(cipherText);
String signatureString = Base64.getEncoder().encodeToString(signature);
// 添加有效期信息
long now = new Date().getTime();
long expireTime = now + 5 * 60 * 1000; // 5分钟有效期
String expireTimeString = String.valueOf(expireTime);
String encryptedData = keyString + ":" + cipherTextString + ":" + signatureString + ":" + expireTimeString;
return Base64.getEncoder().encodeToString(encryptedData.getBytes());
}
// 对加密字符串进行解密和
public static String decryptAndVerify(String encryptedData) throws Exception {
byte[] encryptedDataBytes = Base64.getDecoder().decode(encryptedData);
String encryptedDataString = new String(encryptedDataBytes);
String[] parts = encryptedDataString.split(":");
if (parts.length != 4) {
throw new IllegalArgumentException("Invalid encrypted data format.");
}
String keyString = parts[0];
String cipherTextString = parts[1];
String signatureString = parts[2];
String expireTimeString = parts[3];
long expireTime = Long.parseLong(expireTimeString);
if (new Date().getTime() > expireTime) {
throw new IllegalArgumentException("Encrypted data has expired.");
}
byte[] keyBytes = Base64.getDecoder().decode(keyString);
SecretKey key = new SecretKeySpec(keyBytes, AES_ALGORITHM);
byte[] cipherText = Base64.getDecoder().decode(cipherTextString);
byte[] signature = Base64.getDecoder().decode(signatureString);
if (!verifySignature(cipherText, signature, key)) {
throw new IllegalArgumentException("Invalid signature.");
}
byte[] plainText = aesDecrypt(cipherText, key);
return new String(plainText);
}
在加密时,首先使用generateAESKey方法生成一个AES密钥,然后使用aesEncrypt方法对请求参数进行加密,再使用generateSignature方法对加密后的请求参数进行数字签名。加密后的请求参数、数字签名、密钥等信息通过Base64编码后拼接成一个字符串,并添加有效期信息。
在验证时,首先将加密字符串进行Base64解码,然后解析出密钥、加密后的请求参数、数字签名和有效期信息。通过对有效期信息的校验,判断加密字符串是否过期。然后通过Base64解码密钥,并使用密钥对加密后的请求参数进行解密。接着使用verifySignature方法对解密后的请求参数进行数字签名验证,判断请求参数是否被篡改过。