公司的采购的简单云(ezOne.work)的DevOps平台,研究了一下他的前端的登录界面的用户输入密码的加密算法(JavaScript)中,写了一段java进行加密处理的代码,特记录备忘
package org.example.util;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.Security;
import java.util.Base64;
public class SM4EncriptUtil {
static {
// 检查是否已经注册了BouncyCastle提供者,如果没有则注册
if (Security.getProvider("BC") == null) {
Security.addProvider(new BouncyCastleProvider());
}
}
private static final String ALGORITHM = "SM4/ECB/NoPadding";
/**
* 等效于 JS 的 sm4PasswordEncode(password, key)
* 使用ECB模式和PKCS7填充
*
* @param password 明文密码
* @param key 16 字节密钥(如 "1234567890abcdef")
* @return 十六进制编码的密文
*/
public static String sm4PasswordEncode(String password, String key) {
try {
// 先进行PKCS7填充
byte[] passwordBytes = password.getBytes("UTF-8");
byte[] paddedBytes = pkcs7Padding(passwordBytes);
Cipher cipher = Cipher.getInstance(ALGORITHM);
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes("UTF-8"), "SM4");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] encrypted = cipher.doFinal(paddedBytes);
// 直接返回十六进制字符串,而不是Base64编码
return bytesToHex(encrypted);
} catch (Exception e) {
throw new RuntimeException("SM4 encrypt error", e);
}
}
/**
* PKCS7填充实现
* @param data 原始数据
* @return 填充后的数据
*/
private static byte[] pkcs7Padding(byte[] data) {
int blockSize = 16; // SM4块大小为16字节
int paddingSize = blockSize - (data.length % blockSize);
byte[] paddedData = new byte[data.length + paddingSize];
System.arraycopy(data, 0, paddedData, 0, data.length);
// 填充paddingSize个字节,每个字节的值都是paddingSize
for (int i = data.length; i < paddedData.length; i++) {
paddedData[i] = (byte) paddingSize;
}
return paddedData;
}
/**
* 将字节数组转换为十六进制字符串
* @param bytes 字节数组
* @return 十六进制字符串
*/
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
}
package org.example;
import org.example.util.SM4EncriptUtil;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.util.Base64;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.security.Security;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class Main {
public static String encryptPassword(String pwd) throws Exception{
String key = "ezOne68330710717"; // 16 字节
String result = SM4EncriptUtil.sm4PasswordEncode(pwd, key);
System.out.println("Encrypted: " + result);
return result;
}
public static void main(String[] args) throws Exception {
encryptPassword(encryptPassword("lyz****password"));
}
}
/**
经过双重加密:
输出如下:
Encrypted: fc59a84c1c2a389b91450638dd6c01fc
Encrypted: 25a22fc4d547bdb4ead99f214ed071c30c679d3f9bf7b3e3c5ef26155b7c647154e1b66d1f9145e6e24c73e598af243f
*/
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
6138

被折叠的 条评论
为什么被折叠?



