在模型推理链路中,当用户需要对请求体中的input字段值进行加密以确保输入的安全性时,可以参考本文档通过加密方式接入模型推理功能。本指导适用于需要自定义密钥的场景。
步骤1:获取RSA的公钥
请参考获取RSA的公钥获取public_key和public_key_id。
步骤2:生成AES密钥
//获取KeyGenerator实例并指定AES算法
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
//通过提供来源强大的随机源的种子来初始化SecureRandom
SecureRandom secureRandom = new SecureRandom();
//初始化KeyGenerator, GCM通常使用128位的块大小,这里指定了256位的AES密钥长度
keyGen.init(256, secureRandom);
//生成密钥
//生成AES密钥
SecretKey secretKey = keyGen.generateKey();
//获取密钥的byte数组
byte[] keyBytes = secretKey.getEncoded();
//对密钥byte数组进行base64编码
String base64Key = Base64.encodeBase64String(keyBytes);
步骤3:从获取的RSA公钥生成PublicKey
public static PublicKey getPublicKeyFromString(String publicKey){
byte[] keyBytes = Base64.decodeBase64(key);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);
}
步骤4:通过RSA公钥对AES密钥进行加密
public static String encrypt(String base64Key, PublicKey publicKey){
Cipher cipher = Cipher.getInstance("RSA");
//1为加密模式
cipher.init(1, publicKey);
byte[] encryptedBytes = cipher.doFinal(base64Key.getBytes());
return Base64.encodeBase64String(encryptedBytes);
}
步骤5:通过AES的GCM模式加密时还需要指定iv,tag
iv默认是MDAwMDAwMDAwMDAw
,即12个0经过base64编码后的值。
tag的长度为128。
String iv = "000000000000";
byte[] IV = iv.getBytes();
String base64Iv = Base64.encodeBase64String(IV);
System.out.println("IV:" + base64Iv);
步骤6:AES对输入的input进行加密
input参数说明
//其中plainText为文本类型
byte[] content = plainText.getBytes(StandardCharsets.UTF_8)
//其中plainText为二进制的base64编码结果
byte[] content = Base64.decodeBase64(plainText)
对输入文本 plainText 使用AES-GCM模式加密,并将结果编码为Base64字符串
public static String encrypt(byte[] content, String key, String iv) {
// 创建密码器
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
// 初始化为加密模式的密码器
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128,
Base64.decodeBase64(iv));
//1为加密模式
cipher.init(1, new
SecretKeySpec(Base64.decodeBase64(key), "AES"), gcmParameterSpec);
// 加密
byte[] result = cipher.doFinal(content);
//通过Base64转码返回
return Base64.encodeBase64String(result);
}
步骤7:AES对输出的output进行解密
解密操作示例。
//byte[] content = Base64.decodeBase64(cipherBody)
public static byte[] decrypt(byte[] content, String key, String iv) {
//实例化
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
//使用密钥初始化,设置为解密模式
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128,
Base64.decodeBase64(iv));
//2为解密模式
cipher.init(2, new
SecretKeySpec(Base64.decodeBase64(key), "AES"),
gcmParameterSpec);
//执行操作
return cipher.doFinal(content);
}
解密结果示例。
//解密的结果
//二进制
String plainText = Base64.encodeBase64String(bodyPlainByte);
//文本
String plainText = new String(bodyPlainByte, StandardCharsets.UTF_8);
核心代码示例
以下为核心代码示例,并非完整可运行的代码。
String publicKey = "MIIBIjANBgkq***hDAQAB"; //替换为实际获取的值
String publicKeyId = "1703591764000"; //替换为实际获取的值
String iv = "MDAwMDAwMDAwMDAw";
//生成AES密钥
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = new SecureRandom();
keyGen.init(256, secureRandom);
SecretKey secretKey = keyGen.generateKey();
byte[] keyBytes = secretKey.getEncoded();
String base64Key = Base64.encodeBase64String(keyBytes);
//使用公钥对AES进行加密
byte[] keyBytes = Base64.decodeBase64(publicKey);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pubKey = kf.generatePublic(spec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(1, pubKey);
byte[] encryptedBytes = cipher.doFinal(base64Key.getBytes());
String encryptAesKey = Base64.encodeBase64String(encryptedBytes);
//对推理链路中请求的body中input字段的值进行加密, 其中palinTest为input字段的值
byte[] content = plainText.getBytes(StandardCharsets.UTF_8);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128,
Base64.decodeBase64(iv));
cipher.init(1, new
SecretKeySpec(Base64.decodeBase64(key), "AES"), gcmParameterSpec);
byte[] result = cipher.doFinal(content);
String encryptInput = Base64.encodeBase64String(result);
//请求推理
OkHttpClient okHttpClient = new OkHttpClient().newBuilder().build();
JSONObject jsonBody = new JSONObject();
jsonObject.put("model", "qwen-max");
jsonObject.put("input", encryptInput);
RequestBody body = RequestBody.create(
MediaType.parse("application/json"), jsonBody.toJSONString());
JSONObject headerJson = new JSONObject();
headerJson.put("Content-Type", "application/json");
headerJson.put("Accept", "application/json");
headerJson.put("Authorization", "xxx");
String encryptHeaderValue = "{\"public_key_id\": \""+ publicKeyId +"\",}";
encryptHeaderValue = encryptHeaderValue +
"\"encrypt_key\": \""+ encryptAesKey +"\", \"iv\": \""+ iv +"\"}";
headerJson.put("X-DashScope-EncryptionKey", encryptHeaderValue);
Headers headers = Headers.of(JSONObject.parseObject(headerJson.toString(), Map.class);
String url = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation?request_id=test_222_444";
Request request = new Request.Builder()
.url(url)
.post(body)
.headers(headers)
.build();
String response = okHttpClient.newCall(request).execute().body().string():
JSONObject responseJson = JSONObject.parseObject(reponse, JSONObject.class);
String outputCipher= responseJson.getString("output");
//解密
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding")
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128,
Base64.decodeBase64(iv))
cipher.init(2, new
SecretKeySpec(Base64.decodeBase64(base64Key), "AES"),
gcmParameterSpec);
byte[] outputCipherContent = Base64.decodeBase64(outputCipher)
String plainOutput = Base64.encodeBase64String(cipher.doFinal(outputCipherContent));
System.out.println("输出的内容是:" + plainOutput);
文档内容是否对您有帮助?