xlang加解密算法支持说明
xlang2025-04-05 20:35:36xlang V5.0 起对算法的支持情况
加密算法
| 算法 | 名称 | 模式/签名算法 | 填充方案 | 说明 |
| AES | AES/<padding> | / | PKCS5Padding / PKCS7Padding / ISO10126 / ISO7816-4/ANSI923Padding/NoPadding / ZeroPadding | AES 加密(PKCS5Padding和PKCS7Padding等效) |
| AES | AES/EBC/padding | ecb | PKCS5Padding / PKCS7Padding | |
| AES | AES/CBC/padding | cbc | PKCS7Padding / ISO10126 / ZeroPadding | |
| AES | AES/CFB1/padding | cfb1 | NoPadding | |
| AES | AES/CFB8/padding | cfb8 | NoPadding | |
| AES | AES/CFB128/padding | cfb128 | NoPadding | |
| AES | AES/OFB/padding | ofb | NoPadding | |
| AES | AES/CTR/padding | ctr | NoPadding | |
| AES | AES/CCM/padding/taglen | ccm | NoPadding | taglen为认证标签长度,如 AES/CCM/NoPadding/128 |
| AES | AES/GCM/padding/taglen | gcm | NoPadding | taglen为认证标签长度,如 AES/GCM/NoPadding/128 |
| AES | AES/XTS/padding | xts | NoPadding | |
| AES | AES/WRAP/padding | wrap | NoPadding | |
| AES | AES/WRAP_PAD | wrap_pad | / | 不可指定padding |
| AES | AES/OCB/padding | ocb | NoPadding | |
| AES | AES/CBC-HMAC-SHA1/padding | cbc-hmac-sha1 | PKCS5Padding / PKCS7Padding | |
| AES | CBC-HMAC-SHA256 | cbc-hmac-sha256 | PKCS5Padding / PKCS7Padding | |
| RSA | RSA/[ECB]/<padding> | / | PKCS1Padding/SSLV23Padding/OAEPPadding/X931Padding/PKCS1PSSPadding/NoPadding | ECB 为兼容保留,无实际意义 |
| RSA | RSA/ECB/OEAPWithSha-1AndMGF1Padding | sha-1 | OEAPPadding | |
| RSA | RSA/ECB/OEAPWithSha-224AndMGF1Padding | sha-224 | OEAPPadding | |
| RSA | RSA/ECB/OEAPWithSha-256AndMGF1Padding | sha-256 | OEAPPadding | |
| RSA | RSA/ECB/OEAPWithSha-384AndMGF1Padding | sha-384 | OEAPPadding | |
| RSA | RSA/ECB/OEAPWithSha-512AndMGF1Padding | sha-512 | OEAPPadding | |
| RSA | RSA/ECB/OEAPWithSha-512-224AndMGF1Padding | sha-512-224 | OEAPPadding | |
| RSA | RSA/ECB/OEAPWithSha-512-256AndMGF1Padding | sha-512-256 | OEAPPadding | |
| RSA | RSA/ECB/OEAPWithSha-3-224AndMGF1Padding | sha-3-224 | OEAPPadding | |
| RSA | RSA/ECB/OEAPWithSha-3-256AndMGF1Padding | sha-3-256 | OEAPPadding | |
| RSA | RSA/ECB/OEAPWithSha-3-384AndMGF1Padding | sha-3-384 | OEAPPadding | |
| RSA | RSA/ECB/OEAPWithSha-3-512AndMGF1Padding | sha-3-512 | OEAPPadding | |
| RSA | RSA/ECB/OEAPWithShake128AndMGF1Padding | shake128 | OEAPPadding | |
| RSA | RSA/ECB/OEAPWithShake256AndMGF1Padding | shake256 | OEAPPadding | |
| RSA | RSA/ECB/OEAPWithSm3AndMGF1Padding | sm3 | OEAPPadding |
加密算法命名规则 : 算法名称/模式/填充模式, 如 AES/GCM/PKCS5Padding (不区分大小写)
注意: OAEP填充方式必须指定哈希函数和MGF,根据规范,MGF1 是 OAEP 唯一支持的掩码生成函数,所以是唯一且必须选项。
散列算法
| MD5 | md5 | / |
| HmacSHA256 | HmacSHA256 | / |
| SHA256 | SHA256 | / |
| SHA-1 | SHA-1 | / |
| SM3 | SM3 | / |
注意:区分大小写
签名算法
| 加密算法 | 散列组合 | 说明 |
| RSA | MD5|SHA1|SHA256|SHA384|SHA512 | / |
| DSA | MD5|SHA1|SHA256|SHA384|SHA512 | / |
| ECDSA | MD5|SHA1|SHA256|SHA384|SHA512 | / |
签名算法命名规则: 散列算法(大写)with(小写)加密算法(大写) 如: SHA256withRSA (需区分大小写)
示例
使用 AES/GCM/NoPadding/128 加解密
//加密
String encrypt(String ciphertext , String associated_data, String nonce,String v3key){
// 提取字符串数据
byte [] data = ciphertext.getBytes();
// 获取加密实例 算法类型为AEC 密码模式为GCM 无填充 128位认证标签
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding/128");
//构造一个Key 实例
Key key = KeyFactory.getInstance("AES").generateKey ("AES", 0);
//加载Key数据
key.load(v3key.getBytes(), 0, v3key.length(), nilptr);
//初始化加密实例
cipher.init(Cipher.ENCRYPT_MODE, key, nonce.getBytes());
//计算AAD数据
cipher.updateAAD(associated_data.getBytes(), 0, associated_data.length());
// 加密数据
data = cipher.doFinal(data, 0, data.length);
//转为BASE64字符串输出
return Base64.encodeToString(data, false);
}
//解密
String decrypt(String ciphertext , String associated_data, String nonce,String v3key){
// 提取字符串数据
byte [] data = Base64.decodeString(ciphertext);
// 获取加密实例 算法类型为AEC 密码模式为GCM 无填充 128位认证标签
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding/128");
//构造一个Key 实例
Key key = KeyFactory.getInstance("AES").generateKey ("AES", 0);
//加载Key数据
key.load(v3key.getBytes(), 0, v3key.length(), nilptr);
//初始化加密实例为解密模式
cipher.init(Cipher.DECRYPT_MODE, key, nonce.getBytes());
//计算AAD数据
cipher.updateAAD(associated_data.getBytes(), 0, associated_data.length());
// 加密数据
data = cipher.doFinal(data, 0, data.length);
//转为BASE64字符串
return new String(data);
}
构造Key 注意事项:
KEY支持的算法预设 RSA \ AES
创建KEY实例代码:
//"RSA“ 为算法, Key.PRIVATE_KEY 指示是公钥还是私钥
Key key = KeyFactory.getInstance ("RSA").generateKey ("RSA", Key.PRIVATE_KEY);
//加载PEM 格式的key数据
key.load (pem, 0, pem.length, "PEM");
Key 数据格式分为 PEM和DER,PEM格式一般以 -----BEGIN* 开头 以 -----END* 结尾,如不指定格式,内部会做简单识别。
签名示例代码:
String APIV3Sign(Key _key, String message){
Signature sign = Signature.getInstance("SHA256withRSA");
sign.initSign(_key);
byte [] data = message.getBytes();
sign.update(data,0,data.length);
byte [] res = sign.sign();
return Base64.encodeToString(res,false);
}
RSA 生成Key 说明
第一步: 使用 KeyFactory.getInstance("RSA") 获取支持RSA的KeyFactory;
第二步: 使用第一步获得的 KeyFactory 调用 generateKey("RSA", Key.PRIVATE_KEY) 创建一个Key 私钥实例。
第三步: 设置 RSA key 的bits 长度和常数e (使用 setParam)
第四步: 调用 key 的create方法,建立 key,
第五步: 通过第一步获得的 KeyFactory 生成公钥:
具体实现如下:
// 新建 RSA 私钥实例
Key key = KeyFactory.getInstance("RSA").generateKey("RSA", Key.PRIVATE_KEY);
key.setParam(Key.RSA_BITS, 1024); //设置长度 1024位
key.setParam(Key.RSA_e, Key.RSA_E_F4);//设置常数E 65537
if (key.create()){ // 创建key
Key publicKey = KeyFactory.getInstance("RSA").generateKey(key, Key.PUBLIC_KEY); // 生成公钥
byte [] prikey_data = key.getData(); // 获取私钥数据
_system_.consoleWrite("\n\npri key:" + Base64.encodeToString(prikey_data, false)); //打印私钥数据
byte [] pubkey_data = publicKey.getData(); // 获取公钥数据
_system_.consoleWrite("\n\npub key:" + Base64.encodeToString(pubkey_data, false)); //打印公钥数据
}
RSA 加解密说明
严格意义上RSA公钥不能用于解密, 私钥不能用于加密,例如使用RSA/ECB/OAEPWithSHA-1AndMGF1Padding 的使用公钥解密将会失败抛出异常,尽管底层的函数库提供了支持相反操作的功能,但仍需要注意调用失败的可能性。
注意: 使用MGF1Padding的OAEP填充方案时,只能通过私钥进行解密。
RSA 加解密实例:
Cipher cipher = Cipher.getInstance("RSA"); // 获取Cipher 对象
cipher.init(Cipher.ENCRYPT_MODE, key, nilptr); //使用上一步的 私钥初始化
data = cipher.doFinal(nilptr, 0, 0); // 加密数据并返回结果
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSM3AndMGF1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey, nilptr);
data = cipher.doFinal("12345678901234567890".getBytes(), 0, 20);
cipher = Cipher.getInstance("RSA/ECB/OAEPWithSM3AndMGF1Padding");
cipher.init(Cipher.DECRYPT_MODE, key, nilptr);
data = cipher.doFinal(data, 0, data.length);
加解密和签名相关虽然部分方法以返回值表示状态,但某些情况下仍会抛出异常, 除了常规以返回值判断外,仍需使以 try 块包裹。
其他
此外,xlang 标准库还提供了以C语言方式(面向过程的方式调用加解密), 见 Crypto 类,但需注意,每个过程均依赖 long 类型句柄,用完后需要手动释放,否则会泄露。
使用示例:
byte [] data = "123456789".getBytes(); // 准备数据
long hCrypto = Crypto.rsa_init(); // 初始化一个 rsa 的句柄
Crypto.rsa_create(hCrypto, 1024); //创建
byte[] pbkey = Crypto.rsa_getPublicKey(hCrypto); //获取公钥
byte[] prkey = Crypto.rsa_getPrivateKey(hCrypto); //获取私钥
byte[] pben = Crypto.rsa_privateEncrypto(hCrypto, data, 0, data.length, Crypto.PKCS1Padding); // 加密
byte[] pbde = Crypto.rsa_publicDecrypto(hCrypto, pben, 0, pben.length, Crypto.PKCS1Padding); //解密
Crypto.rsa_close(hCrypto); //记得关闭句柄
注意:此类在未来将被弃用。
上一篇:xlang webserver 用法详解下一篇:xlang5.0更新说明

