Browse Source

网页版 & 支持测试目前使用的所有加密方式

master
Anner 4 years ago
parent
commit
577978958c
  1. 35
      build.gradle
  2. 5
      src/main/java/com/fr/password/Constants.java
  3. 14
      src/main/java/com/fr/password/Runner.java
  4. 17
      src/main/java/com/fr/password/controller/PageController.java
  5. 38
      src/main/java/com/fr/password/controller/PasswordController.java
  6. 89
      src/main/java/com/fr/password/controller/StorageController.java
  7. 43
      src/main/java/com/fr/password/controller/TransmissionController.java
  8. 47
      src/main/java/com/fr/password/listerner/CommandRunner.java
  9. 22
      src/main/java/com/fr/password/service/PasswordService.java
  10. 76
      src/main/java/com/fr/password/service/StorageService.java
  11. 24
      src/main/java/com/fr/password/service/TransmissionService.java
  12. 181
      src/main/java/com/fr/password/tool/SecurityToolbox.java
  13. 10
      src/main/java/com/fr/password/tool/factory/SecretHelper.java
  14. 39
      src/main/java/com/fr/password/tool/keys/CustomSM2Keys.java
  15. 13
      src/main/java/com/fr/password/tool/keys/RSAKeysHandler.java
  16. 12
      src/main/java/com/fr/password/tool/keys/SM2KeysHandler.java
  17. 4
      src/main/java/com/fr/password/tool/ui/TopPanel.java
  18. 2
      src/main/java/com/fr/password/tool/util/BCECUtil.java
  19. 192
      src/main/java/com/fr/password/tool/util/sm2/SM4Util.java
  20. 2
      src/main/java/com/fr/password/tool/util/smx/SM2Cipher.java
  21. 2
      src/main/java/com/fr/password/tool/util/smx/SM2KeyPair.java
  22. 2
      src/main/java/com/fr/password/tool/util/smx/SM2Util.java
  23. 2
      src/main/java/com/fr/password/tool/util/smx/SM3Util.java
  24. 410
      src/main/java/com/fr/password/tool/util/smx/SM4Util.java
  25. 3
      src/main/resources/application.properties
  26. 147
      src/main/resources/static/index.html
  27. 289
      src/main/resources/static/index.js
  28. 1
      src/test/java/com/fr/password/tool/keys/RSAKeysHandlerTest.java
  29. 11
      src/test/java/com/fr/password/tool/keys/SM2KeysHandlerTest.java
  30. 10
      src/test/java/com/fr/password/tool/util/smx/SM2UtilTest.java

35
build.gradle

@ -1,7 +1,33 @@
buildscript {
ext {
springIOVersion = '1.0.0.RELEASE'
springBootVersion = '2.2.6.RELEASE'
}
repositories {
jcenter()
mavenCentral()
maven { url "http://repo.spring.io/release" }
maven { url "http://repo.spring.io/milestone" }
maven { url "http://repo.spring.io/snapshot" }
maven { url "https://plugins.gradle.org/m2/" }
}
dependencies {
classpath "io.spring.gradle:dependency-management-plugin:${springIOVersion}"
classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
}
}
plugins {
id 'java'
id 'idea'
id 'java-library'
id 'maven-publish'
}
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group 'org.example'
version '1.0-SNAPSHOT'
@ -12,16 +38,15 @@ repositories {
dependencies {
compile group: 'cn.hutool', name: 'hutool-all', version: '5.4.2'
compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.66'
compile 'org.springframework.boot:spring-boot-starter-web:2.2.6.RELEASE'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
jar {
archivesBaseName = 'password-generator'
archivesBaseName = 'encryption-verify-tool'
archiveVersion = '0.0.1'
manifest {
attributes 'Main-Class': 'com.fr.password.tool.Runner'
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
attributes "Manifest-Version": 1.0,
'Main-Class': 'com.fr.password.Runner'
}
}

5
src/main/java/com/fr/password/Constants.java

@ -0,0 +1,5 @@
package com.fr.password;
public class Constants {
public static final String DEFAULT_KEY = "";
}

14
src/main/java/com/fr/password/Runner.java

@ -0,0 +1,14 @@
package com.fr.password;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class Runner extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Runner.class, args);
}
}

17
src/main/java/com/fr/password/controller/PageController.java

@ -0,0 +1,17 @@
package com.fr.password.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@RestController
public class PageController {
// 定向到主页的静态资源文件
@RequestMapping("/encryption/for/test")
public void toIndex(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.sendRedirect("http://127.0.0.1:10086/index.html");
}
}

38
src/main/java/com/fr/password/controller/PasswordController.java

@ -0,0 +1,38 @@
package com.fr.password.controller;
import com.fr.password.service.PasswordService;
import com.fr.password.tool.SecurityToolbox;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
/**
* desc
*
* @author Anner
* created on 2020-10-19
*/
@RestController
@RequestMapping("/password/encrypt")
public class PasswordController {
@Autowired
private PasswordService passwordService;
@RequestMapping("/sha")
public String sha(@RequestParam String plainText) throws IOException {
return passwordService.sha(filter(plainText));
}
@RequestMapping("/sm3")
public String sm3(@RequestParam String plainText) throws IOException {
return passwordService.sm3(filter(plainText));
}
private String filter(String origin) throws IOException {
return new String(SecurityToolbox.getInstance().base642Byte(origin));
}
}

89
src/main/java/com/fr/password/controller/StorageController.java

@ -0,0 +1,89 @@
package com.fr.password.controller;
import com.fr.password.Constants;
import com.fr.password.service.StorageService;
import com.fr.password.tool.SecurityToolbox;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.spec.InvalidKeySpecException;
@RestController
@RequestMapping("/storage")
public class StorageController {
@Autowired
private StorageService storageService;
@RequestMapping("/encrypt/sm2")
private String sm2Encrypt(@RequestParam String plainText, @RequestParam String key) throws InvalidCipherTextException, InvalidKeySpecException, NoSuchAlgorithmException, NoSuchProviderException, IOException {
if (key.equals(Constants.DEFAULT_KEY)) {
return storageService.sm2Encrypt(filter(plainText), key, false);
}
return storageService.sm2Encrypt(filter(plainText), key);
}
@RequestMapping("/decrypt/sm2")
private String sm2Decrypt(@RequestParam String cipherText, @RequestParam String key) throws Exception {
if (key.equals(Constants.DEFAULT_KEY)) {
return storageService.sm2Decrypt(filter(cipherText), key, false);
}
return storageService.sm2Decrypt(filter(cipherText), key);
}
@RequestMapping("/encrypt/sm2/custom")
private String sm2CustomEncrypt(@RequestParam String plainText) throws Exception {
return storageService.sm2CustomEncrypt(filter(plainText));
}
@RequestMapping("/decrypt/sm2/custom")
private String sm2CustomDecrypt(@RequestParam String cipherText) throws Exception {
return storageService.sm2CustomDecrypt(filter(cipherText));
}
@RequestMapping("/encrypt/sm2/seed")
private String sm2EncryptWithSeed(@RequestParam String plainText,@RequestParam String seed1,@RequestParam String seed2,@RequestParam String seed3) throws IOException {
return storageService.sm2EncryptWithSeed(plainText,filter(seed1),filter(seed2),filter(seed3));
}
@RequestMapping("/decrypt/sm2/seed")
private String sm2DecryptWithSeed(@RequestParam String cipherText,@RequestParam String seed1,@RequestParam String seed2,@RequestParam String seed3) throws IOException {
return storageService.sm2DecryptWithSeed(cipherText,filter(seed1),filter(seed2),filter(seed3));
}
@RequestMapping("/encrypt/rsa")
private String rsaEncrypt(@RequestParam String plainText, @RequestParam String key) throws IOException {
if (key.equals(Constants.DEFAULT_KEY)) {
return storageService.rsaEncrypt(filter(plainText), key, false);
}
return storageService.rsaEncrypt(filter(plainText), key, true);
}
@RequestMapping("/decrypt/rsa")
private String rsaDecrypt(@RequestParam String cipherText, @RequestParam String key) throws IOException {
if (key.equals(Constants.DEFAULT_KEY)) {
return storageService.rsaDecrypt(filter(cipherText), key, false);
}
return storageService.rsaDecrypt(filter(cipherText), key, true);
}
@RequestMapping("/encrypt/rsa/seed")
private String rsaEncryptWithSeed() {
return null;
}
@RequestMapping("/decrypt/rsa/seed")
private String rsaDecryptWithSeed() {
return null;
}
private String filter(String origin) throws IOException {
return new String(SecurityToolbox.getInstance().base642Byte(origin)).trim().replace("\\n","\n");
}
}

43
src/main/java/com/fr/password/controller/TransmissionController.java

@ -0,0 +1,43 @@
package com.fr.password.controller;
import com.fr.password.service.TransmissionService;
import com.fr.password.tool.SecurityToolbox;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
@RestController
@RequestMapping("/transmission")
public class TransmissionController {
@Autowired
private TransmissionService transmissionService;
@RequestMapping("/encrypt/aes")
private String aesEncrypt(@RequestParam String plainText, @RequestParam String key) throws Exception {
return transmissionService.aesEncrypt(filter(plainText), filter(key));
}
@RequestMapping("/decrypt/aes")
private String aesDecrypt(@RequestParam String cipherText, @RequestParam String key) throws Exception {
return transmissionService.aesDecrypt(filter(cipherText),filter(key));
}
@RequestMapping("/encrypt/sm4")
private String sm4Encrypt(@RequestParam String plainText, @RequestParam String key) throws Exception {
return transmissionService.sm4Encrypt(filter(plainText),filter(key));
}
@RequestMapping("/decrypt/sm4")
private String sm4Decrypt(@RequestParam String cipherText, @RequestParam String key) throws Exception {
return transmissionService.sm4Decrypt(filter(cipherText), filter(key));
}
private String filter(String origin) throws IOException {
return new String(SecurityToolbox.getInstance().base642Byte(origin)).trim().replace("\\n","\n");
}
}

47
src/main/java/com/fr/password/listerner/CommandRunner.java

@ -0,0 +1,47 @@
package com.fr.password.listerner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Component
public class CommandRunner implements CommandLineRunner {
@Value("${project.index}")
private String path;
@Override
public void run(String... args) throws Exception {
// 自动跳转到主页
openIndexPage();
}
private void openIndexPage() throws Exception {
// 自动打开浏览器
String osName = System.getProperty("os.name");
if (osName.startsWith("Mac")) {
Class<?> fileMgr = Class.forName("com.apple.eio.FileManager");
Method openURL = fileMgr.getDeclaredMethod("openURL", new Class[]{String.class});
openURL.invoke(null, new Object[]{path});
} else if (osName.startsWith("Windows")) {
Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + path);
} else {
// Unix or Linux的打开方式
String[] browsers = {"firefox", "opera", "konqueror", "epiphany", "mozilla", "netscape"};
String browser = null;
for (int count = 0; count < browsers.length && browser == null; count++)
if (Runtime.getRuntime().exec(new String[]{"which", browsers[count]}).waitFor() == 0) {
browser = browsers[count];
}
if (browser == null) {
throw new Exception("Could not find web browser");
} else {
// 这个值在上面已经成功的得到了一个进程。
Runtime.getRuntime().exec(new String[]{browser, path});
}
}
}
}

22
src/main/java/com/fr/password/service/PasswordService.java

@ -0,0 +1,22 @@
package com.fr.password.service;
import com.fr.password.tool.SecurityToolbox;
import org.springframework.stereotype.Service;
/**
* desc
*
* @author Anner
* created on 2020-10-19
*/
@Service
public class PasswordService {
public String sha(String plainText) {
return SecurityToolbox.getInstance().sha256(plainText);
}
public String sm3(String plainText){
return SecurityToolbox.getInstance().sm3Encrypt(plainText);
}
}

76
src/main/java/com/fr/password/service/StorageService.java

@ -0,0 +1,76 @@
package com.fr.password.service;
import com.fr.password.tool.SecurityToolbox;
import com.fr.password.tool.factory.SecretHelper;
import com.fr.password.tool.keys.CustomSM2Keys;
import com.fr.password.tool.keys.RSAKeysHandler;
import com.fr.password.tool.keys.SM2KeysHandler;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.spec.InvalidKeySpecException;
@Service
public class StorageService {
public String sm2Encrypt(String plainText, String key) throws InvalidCipherTextException, InvalidKeySpecException, NoSuchAlgorithmException, NoSuchProviderException, IOException {
return sm2Encrypt(plainText, key, true);
}
public String sm2Encrypt(String plainText, String key, boolean isCustom) throws InvalidKeySpecException, InvalidCipherTextException, NoSuchAlgorithmException, NoSuchProviderException, IOException {
if (isCustom) {
return SecurityToolbox.getInstance().sm2Encrypt(plainText, SecretHelper.loadFromText(filter(key)).get(SecretHelper.PRIVATE_KEY));
}
return SecurityToolbox.getInstance().sm2Encrypt(plainText, SM2KeysHandler.getInstance().getDefaultKey());
}
public String sm2Decrypt(String cipherText, String key) throws Exception {
return sm2Decrypt(cipherText, key, true);
}
public String sm2Decrypt(String cipherText, String key, boolean isCustom) throws Exception {
if (isCustom) {
return SecurityToolbox.getInstance().sm2Decrypt(cipherText, SecretHelper.loadFromText(filter(key)).get(SecretHelper.PRIVATE_KEY));
}
return SecurityToolbox.getInstance().sm2Decrypt(cipherText, SM2KeysHandler.getInstance().getDefaultKey());
}
public String sm2EncryptWithSeed(String plainText, String seed1, String seed2, String seed3) {
return null;
}
public String sm2DecryptWithSeed(String cipherText, String seed1, String seed2, String seed3) {
return null;
}
public String sm2CustomEncrypt(String plainText) throws Exception {
return CustomSM2Keys.getInstance().encrypt(plainText);
}
public String sm2CustomDecrypt(String cipherText) throws Exception {
return CustomSM2Keys.getInstance().decrypt(cipherText);
}
public String rsaEncrypt(String plainText, String key, boolean isCustom) throws IOException {
if (isCustom) {
return SecurityToolbox.getInstance().rsaEncrypt(plainText, SecretHelper.loadFromText(filter(key)).get(SecretHelper.PUBLIC_KEY));
}
return SecurityToolbox.getInstance().rsaEncrypt(plainText, RSAKeysHandler.getInstance().getDefaultPublicKey());
}
public String rsaDecrypt(String cipherText, String key, boolean isCustom) throws IOException {
if (isCustom) {
return SecurityToolbox.getInstance().rsaDecrypt(cipherText, SecretHelper.loadFromText(filter(key)).get(SecretHelper.PRIVATE_KEY));
}
return SecurityToolbox.getInstance().rsaDecrypt(cipherText, RSAKeysHandler.getInstance().getDefaultPrivateKey());
}
private String filter(String origin) throws IOException {
return new String(SecurityToolbox.getInstance().base642Byte(origin));
}
}

24
src/main/java/com/fr/password/service/TransmissionService.java

@ -0,0 +1,24 @@
package com.fr.password.service;
import com.fr.password.tool.SecurityToolbox;
import org.springframework.stereotype.Service;
@Service
public class TransmissionService {
public String aesEncrypt(String plainText, String key) {
return SecurityToolbox.getInstance().aesEncrypt(plainText,key);
}
public String aesDecrypt(String plainText, String key) {
return SecurityToolbox.getInstance().aesDecrypt(plainText,key);
}
public String sm4Encrypt(String plainText, String key) {
return SecurityToolbox.getInstance().sm4Encrypt(plainText,key);
}
public String sm4Decrypt(String plainText, String key) {
return SecurityToolbox.getInstance().sm4Decrypt(plainText,key);
}
}

181
src/main/java/com/fr/password/tool/SecurityToolbox.java

@ -0,0 +1,181 @@
package com.fr.password.tool;
import cn.hutool.core.util.StrUtil;
import com.fr.password.tool.keys.RSAKeysHandler;
import com.fr.password.tool.util.BCECUtil;
import com.fr.password.tool.util.EncodeUtil;
import com.fr.password.tool.util.rsa.RSAUtil;
import com.fr.password.tool.util.smx.SM2Util;
import com.fr.password.tool.util.smx.SM3Util;
import com.fr.password.tool.util.smx.SM4Util;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.springframework.util.StringUtils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
public class SecurityToolbox {
private static SecurityToolbox instance = new SecurityToolbox();
private SecurityToolbox() {
}
public static SecurityToolbox getInstance() {
return instance;
}
public String rsaEncrypt(String plainText, String key) {
PublicKey publicKey = RSAKeysHandler.getInstance().string2PublicKey(key);
return EncodeUtil.byte2Base64(RSAUtil.encrypt(plainText.getBytes(), publicKey));
}
public String rsaDecrypt(String cipherText, String key) throws IOException {
PrivateKey privateKey = RSAKeysHandler.getInstance().string2PrivateKey(key);
return new String(RSAUtil.decrypt(EncodeUtil.base642Byte(cipherText), privateKey), StandardCharsets.UTF_8);
}
public String sm2Encrypt(String plainText, String key) throws
IOException, NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidCipherTextException {
if (StrUtil.isEmpty(plainText) || StrUtil.isEmpty(key)) {
return plainText;
}
String privateKey = new String(base642Byte(key), StandardCharsets.UTF_8);
ECPrivateKeyParameters privateKeyParameters = BCECUtil.convertSEC1ToECPrivateKey(ByteUtils.fromHexString(privateKey));
ECPublicKeyParameters publicKeyParameters = BCECUtil.buildECPublicKeyByPrivateKey(privateKeyParameters);
return byte2Base64(SM2Util.encrypt(publicKeyParameters, plainText.getBytes()));
}
public String sm2Decrypt(String cipherText, String key) throws Exception {
return new String(SM2Util.decrypt(key2ECPrivateKeyParameters(key), base642Byte(cipherText)), StandardCharsets.UTF_8);
}
// fOvwPYPkUmVYjnAO
public String aesEncrypt(String plainText, String password) {
Key secretKey = getEasKey(password);
try {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] p = plainText.getBytes("UTF-8");
byte[] result = cipher.doFinal(p);
return byte2Base64(result);
} catch (Exception e) {
}
return null;
}
/**
* @param cipherText base64后的密文
* @param password 秘钥
* @return
*/
public String aesDecrypt(String cipherText, String password) {
try {
Key secretKey = getEasKey(password);
//默认即为AES/ECB/PKCS5Padding
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] result = cipher.doFinal(base642Byte(cipherText));
return new String(result, "UTF-8");
} catch (Exception e) {
}
return null;
}
// edbfbd27db981534b1356d14f0e9bef9
public String sm4Encrypt(String plainText, String key) {
return byte2Base64(SM4Util.encryptData_ECB(plainText, key));
}
public String sm4Decrypt(String cipherText, String key) {
return new String(SM4Util.decryptData_ECB(cipherText, key), StandardCharsets.UTF_8);
}
private Key getEasKey(String password) {
try {
//eas秘钥长度使用16byte(128位),不足则填充0,多则截取前16
byte[] bytes = password.getBytes("UTF-8");
byte[] key = new byte[16];
for (int i = 0; i < bytes.length && i < key.length; i++) {
key[i] = bytes[i];
}
return new SecretKeySpec(key, "AES");
} catch (Exception e) {
}
return null;
}
public String sha256(String plainTextData) {
if (StringUtils.isEmpty(plainTextData)) {
return plainTextData;
}
try {
byte[] bytes = sha256(plainTextData.getBytes("UTF-8"));
return byteArrayToHexString(bytes);
} catch (UnsupportedEncodingException e) {
}
return plainTextData;
}
private byte[] sha256(byte[] plainTextData) {
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(plainTextData);
return messageDigest.digest();
} catch (Exception e) {
}
return plainTextData;
}
public String sm3Encrypt(String plainText) {
return byteArrayToHexString(SM3Util.hash(plainText.getBytes()));
}
public String byteArrayToHexString(byte[] b) {
StringBuilder hs = new StringBuilder();
String tempStr;
for (int n = 0; b != null && n < b.length; n++) {
tempStr = Integer.toHexString(b[n] & 0XFF);
if (tempStr.length() == 1)
hs.append('0');
hs.append(tempStr);
}
return hs.toString().toLowerCase();
}
public byte[] base642Byte(String base64Key) throws IOException {
BASE64Decoder decoder = new BASE64Decoder();
return decoder.decodeBuffer(base64Key);
}
public String byte2Base64(byte[] bytes) {
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(bytes);
}
public ECPrivateKeyParameters key2ECPrivateKeyParameters(String key) {
try {
String privateKey = new String(base642Byte(key), StandardCharsets.UTF_8);
return BCECUtil.convertSEC1ToECPrivateKey(ByteUtils.fromHexString(privateKey));
} catch (Exception e) {
}
return null;
}
}

10
src/main/java/com/fr/password/tool/factory/SecretHelper.java

@ -32,8 +32,12 @@ public class SecretHelper {
if (StrUtil.isBlank(path)) {
return null;
}
HashMap<String, String> map = new HashMap<String, String>();
String text = FileUtil.readUtf8String(path);
return loadFromText(text);
}
public static Map<String, String> loadFromText(String text) {
HashMap<String, String> map = new HashMap<String, String>();
map.put(PUBLIC_KEY, findMatchedText(text, PUBLIC_PATTERN));
map.put(PRIVATE_KEY, findMatchedText(text, PRIVATE_PATTERN));
return map;
@ -47,8 +51,4 @@ public class SecretHelper {
}
return StrUtil.EMPTY;
}
public static void main(String[] args) {
getKeyPair("/Users/anner/Desktop/key.txt.bak");
}
}

39
src/main/java/com/fr/password/tool/keys/CustomSM2Keys.java

@ -0,0 +1,39 @@
package com.fr.password.tool.keys;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
/**
* desc
*
* @author Anner
* created on 2020-10-19
*/
public class CustomSM2Keys {
private static CustomSM2Keys instance = new CustomSM2Keys();
public static CustomSM2Keys getInstance() {
return instance;
}
private CustomSM2Keys(){
}
String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdm/o3XJLF4Yo4Sx3HyQrk9ZIHiJTqW6NDOS89Vq4V7qZCZkq+ejgk8i8f1cYurJ8XNYJ1qJUXG4zifSaz7eUCQuGbzRSESxmZfCNThKMhzLt/IPuQ6jHBHHBY+hj58lQVHysixKsZ2TvpXNNh2nO/MdEgxToGzX7lj39Vs4HZewIDAQAB";
String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJ2b+jdcksXhijhLHcfJCuT1kgeIlOpbo0M5Lz1WrhXupkJmSr56OCTyLx/Vxi6snxc1gnWolRcbjOJ9JrPt5QJC4ZvNFIRLGZl8I1OEoyHMu38g+5DqMcEccFj6GPnyVBUfKyLEqxnZO+lc02Hac78x0SDFOgbNfuWPf1Wzgdl7AgMBAAECgYAS6hogNLrkhomo8dLUHBtzmMj6oHiGm5K/SYiSyuk/dpF7XH1R2KcOQAZJwsTy6wJ4rZJHfoDN8h95Ot2/MCiQaHGsXyR8Iuifxed8ptzIZSwZDbhO+mZnoFo7UQIyY8hG7wtMGGbj3BGuQ9esKijbmh10gQIUinbK0zCkOiSC6QJBAPwjQJetteX3DRDoiNBjJ2jEYaC6I5w5MZTI2vd9NNPDdepYMVrzzTyn8zvHOiKt/ew52z6r2kw+0+OuSK1eIL0CQQCgBgkoa0n4yUa2s/Rjanqi1Z1cRt9d4ASFFmX7I1Mh7agt8tY2KI/swwRNtQVA7zKso9kWwx0XY6LPFbdcgFKXAkEApniH/x08CddxkwZUvnGY5X0zkDEVreG9MKTknZ7XMDHPOqh7/bcWfMPOvlstsRP7oOoaLWi9urWIpLy/U2fgaQJBAJaS910MD2/E3QAfto8xazH7dPWWTqnDmB0u5Uj5hUkAmmaaAIy3gC4VluATvFzMds9R4Xz0nVQb0d+wHHgy2wMCQAkPlqEGtKk5ZavUJePMRZXTma+hDac7ObvzkxrHq9d9VK10PtaWgmJieD4fEhvCW/mIvwP/iFgr4obe4rQOZvs=";
RSA rsa = new RSA(privateKey, publicKey);
public String encrypt(String s) throws Exception {
return rsa.encryptBase64(StrUtil.bytes(s, CharsetUtil.CHARSET_UTF_8), KeyType.PublicKey);
}
public String decrypt(String s) throws Exception {
return rsa.decryptStr(s, KeyType.PrivateKey);
}
}

13
src/main/java/com/fr/password/tool/keys/RSAKeysHandler.java

@ -19,6 +19,11 @@ public class RSAKeysHandler {
private static RSAKeysHandler instance = null;
private static final String[] DEFAULT = new String[]{
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj0yc/l+39O1XukrG1cA4rmJEDlmfdUZHVWFrFkYA3XvZI9FQIYjx/irVurCtXsgn88xWlvEMAlKQVdU5EDvv5qS+9X83LV6tyShFQ4hVa+s1n+eHhWj3PTTTsELN7SEmaCdzFNAcfXYE+c51mvWSioOktORZ4l9Sh3sQ+b/Gir70hJk+ARI2pE2xmEZQCC1vks8rSaay/LuGE+PBkuK42qbcfWkBhvXb8GqnW2+3A61hFa8VSdZmEq5qqDvCUSBxjVhATgAO57qQof3v13lyn8zk+Fg/KYeT1iuxgpVqYjLARyr2f1hZBiiZT5yNtwVVk3+4uP2AyIh+oNAOujNSawIDAQAB",
"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCPTJz+X7f07Ve6SsbVwDiuYkQOWZ91RkdVYWsWRgDde9kj0VAhiPH+KtW6sK1eyCfzzFaW8QwCUpBV1TkQO+/mpL71fzctXq3JKEVDiFVr6zWf54eFaPc9NNOwQs3tISZoJ3MU0Bx9dgT5znWa9ZKKg6S05FniX1KHexD5v8aKvvSEmT4BEjakTbGYRlAILW+SzytJprL8u4YT48GS4rjaptx9aQGG9dvwaqdbb7cDrWEVrxVJ1mYSrmqoO8JRIHGNWEBOAA7nupCh/e/XeXKfzOT4WD8ph5PWK7GClWpiMsBHKvZ/WFkGKJlPnI23BVWTf7i4/YDIiH6g0A66M1JrAgMBAAECggEAJ8Xt9TSADH0r0ksa8Q0PLmeb2BfMCHLfLbWCUYZQiyjq1eQsx4IJGLCu7chH9ny7ihF3HyH8YVClOw2ZbwYTygKD9gO/Ptp+hcylnN7kRrXcBmvu03qU1Ooqr0t7eIuw60u3x1kT70aojuVdAwuSBtwPBR40TH6Em5Hu3kL6SlvU3F9EBDycH1OsonqOaS3z0F7EdFv7NqYKM1VsvhnkfximTE8ikhxdN4vSko9alJii2wM94Hca3NOI6Ug8IkjNr44qj4jVucYzvEw6d0tcWkQRh22dD2617Yeym0tsx+JxMPvMEcOqF3+VRDqb+xFmRrwTh5z0QU96n8r5NcBasQKBgQDv/0ni1SA7EZ3tDesfHSD0dIYk5U6OESzNwWSlmf13Gu7pg71B439O4VIU5OpGrtuA75xHPE6HcwBoEpQjGCYSMerWNhiwPJbXS/CdJVld8ZiIHDu40xCH96EB7y+yG+wueh0HDk/SjwRAcuL58LJnVVje9SSMK3kgeuYrubjkhwKBgQCY2rUMB0KtEisxv/z/YfAfYbCfqp9AGgLYDZjc7cvqczniv7k4AdP0DSOh4eBPe+1whXahhyQ8zkIKZeaYhCV3awXqQJ0D1BhNlMPKnDNzfGfueRnmcji1goiLcuMApqm+33oebPSnv1D6X88M+05S3husJH+lWM51/8eW0zH//QKBgDShY26fFmZdwqhNuRYlqShytUg6ETQOiCjHFG9Mic0o1uPWxBZC8ZQ2zW1PliDSD8kCwt7MVtxVV+16xYm8rfynfbxkOJ3Na7bjLG0J18NGTBDtQBuUDbgDkgd+kJMalHzMwrjdZpviSShpCWWOZ1FJ4idi0xT6I6H/0aIdJHLZAoGBAIOk4QZx/lfGbRMU0ZU1STQN06s/rJXtkQN4em3UE6phALqr+p4k3OG0qzqRqblq9yzQlUI6fNgtn60K5BX4wbfeoaKFcXVJpoCyngmSi7FrtKsq+0aAmxygRm8rTBxUbZ8pIyivF+qdF+X6u/znNyahid2xNYo3OOFhoAji7Y4VAoGBAOXoMHEE1rQsRQEr0p7BFVGTsSwfFCzbiACA5BmQ/fMas2z4lc44MZYqsVHAqqRqbonF+pK2c+6RHqhVpCPC6NTTlqispcP5OTTW2mSj3JFiyTWxkep3m8JiSrJX/uLQcGJHFomPTznHmYLinNlQXm6Z19zkUFIWxvP/QY5SIzKX"
};
public static RSAKeysHandler getInstance() {
if (instance == null) {
synchronized (RSAKeysHandler.class) {
@ -96,4 +101,12 @@ public class RSAKeysHandler {
}
return EncodeUtil.byte2Base64(privateKey.getEncoded());
}
public String getDefaultPublicKey(){
return DEFAULT[0];
}
public String getDefaultPrivateKey(){
return DEFAULT[1];
}
}

12
src/main/java/com/fr/password/tool/keys/SM2KeysHandler.java

@ -5,8 +5,8 @@ import cn.hutool.log.StaticLog;
import com.fr.password.tool.factory.SecretHelper;
import com.fr.password.tool.util.BCECUtil;
import com.fr.password.tool.util.EncodeUtil;
import com.fr.password.tool.util.sm2.SM2KeyPair;
import com.fr.password.tool.util.sm2.SM2Util;
import com.fr.password.tool.util.smx.SM2KeyPair;
import com.fr.password.tool.util.smx.SM2Util;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
@ -25,6 +25,9 @@ import java.util.Map;
public class SM2KeysHandler {
private static SM2KeysHandler instance = null;
private static final String DEFAULT = "MzA4MjAxNTEwMjAxMDEwNDIwYzQxYTMyYzRhOWMwMTFhYmE0Yzk2NjA4YjUwMDA1NzllNzA2ZmRmZDA2NDE4NjljNmRjNGJkNDY3MmQ1YWI4ZmEwODFlMzMwODFlMDAyMDEwMTMwMmMwNjA3MmE4NjQ4Y2UzZDAxMDEwMjIxMDBmZmZmZmZmZWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmMDAwMDAwMDBmZmZmZmZmZmZmZmZmZmZmMzA0NDA0MjBmZmZmZmZmZWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmMDAwMDAwMDBmZmZmZmZmZmZmZmZmZmZjMDQyMDI4ZTlmYTllOWQ5ZjVlMzQ0ZDVhOWU0YmNmNjUwOWE3ZjM5Nzg5ZjUxNWFiOGY5MmRkYmNiZDQxNGQ5NDBlOTMwNDQxMDQzMmM0YWUyYzFmMTk4MTE5NWY5OTA0NDY2YTM5Yzk5NDhmZTMwYmJmZjI2NjBiZTE3MTVhNDU4OTMzNGM3NGM3YmMzNzM2YTJmNGY2Nzc5YzU5YmRjZWUzNmI2OTIxNTNkMGE5ODc3Y2M2MmE0NzQwMDJkZjMyZTUyMTM5ZjBhMDAyMjEwMGZmZmZmZmZlZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmNzIwM2RmNmIyMWM2MDUyYjUzYmJmNDA5MzlkNTQxMjMwMjAxMDFhMTQ0MDM0MjAwMDQ4NjljY2VkZGM0YzI1ZmMzOGQ3MjZkM2QxOTYyZDgzYjkyMTM4ZmU1MWRlNDE3NzZjOTg1ODc5NGJmZDEwOWNkYTBjOWIwNGNkMzY4MDk3YTQ4ZDk0ODhhNzhmMjRiODA2ODA1NWYzNWMyOTk2OWUxZmFkODQ4MTY3MzVjNDUyNQ==";
public static SM2KeysHandler getInstance() {
if (instance == null) {
synchronized (SM2KeysHandler.class) {
@ -70,6 +73,11 @@ public class SM2KeysHandler {
return null;
}
public String getDefaultKey() {
return DEFAULT;
}
/**
* base64 编码后的私钥
*

4
src/main/java/com/fr/password/tool/ui/TopPanel.java

@ -6,8 +6,8 @@ import com.fr.password.tool.keys.RSAKeysHandler;
import com.fr.password.tool.keys.SM2KeysHandler;
import com.fr.password.tool.util.EncodeUtil;
import com.fr.password.tool.util.rsa.RSAUtil;
import com.fr.password.tool.util.sm2.SM2KeyPair;
import com.fr.password.tool.util.sm2.SM2Util;
import com.fr.password.tool.util.smx.SM2KeyPair;
import com.fr.password.tool.util.smx.SM2Util;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;

2
src/main/java/com/fr/password/tool/util/BCECUtil.java

@ -1,6 +1,6 @@
package com.fr.password.tool.util;
import com.fr.password.tool.util.sm2.SM2Util;
import com.fr.password.tool.util.smx.SM2Util;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Encoding;

192
src/main/java/com/fr/password/tool/util/sm2/SM4Util.java

@ -1,192 +0,0 @@
package com.fr.password.tool.util.sm2;
import com.fr.password.tool.util.GMBaseUtil;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.engines.SM4Engine;
import org.bouncycastle.crypto.macs.CBCBlockCipherMac;
import org.bouncycastle.crypto.macs.GMac;
import org.bouncycastle.crypto.modes.GCMBlockCipher;
import org.bouncycastle.crypto.paddings.BlockCipherPadding;
import org.bouncycastle.crypto.paddings.PKCS7Padding;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
public class SM4Util extends GMBaseUtil {
public static final String ALGORITHM_NAME = "SM4";
public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";
public static final String ALGORITHM_NAME_ECB_NOPADDING = "SM4/ECB/NoPadding";
public static final String ALGORITHM_NAME_CBC_PADDING = "SM4/CBC/PKCS5Padding";
public static final String ALGORITHM_NAME_CBC_NOPADDING = "SM4/CBC/NoPadding";
/**
* SM4算法目前只支持128位即密钥16字节
*/
public static final int DEFAULT_KEY_SIZE = 128;
public static byte[] generateKey() throws NoSuchAlgorithmException, NoSuchProviderException {
return generateKey(DEFAULT_KEY_SIZE);
}
public static byte[] generateKey(int keySize) throws NoSuchAlgorithmException, NoSuchProviderException {
KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);
kg.init(keySize, new SecureRandom());
return kg.generateKey().getEncoded();
}
public static byte[] encrypt_ECB_Padding(byte[] key, byte[] data)
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
Cipher cipher = generateECBCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(data);
}
public static byte[] decrypt_ECB_Padding(byte[] key, byte[] cipherText)
throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
Cipher cipher = generateECBCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.DECRYPT_MODE, key);
return cipher.doFinal(cipherText);
}
public static byte[] encrypt_ECB_NoPadding(byte[] key, byte[] data)
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
Cipher cipher = generateECBCipher(ALGORITHM_NAME_ECB_NOPADDING, Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(data);
}
public static byte[] decrypt_ECB_NoPadding(byte[] key, byte[] cipherText)
throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
Cipher cipher = generateECBCipher(ALGORITHM_NAME_ECB_NOPADDING, Cipher.DECRYPT_MODE, key);
return cipher.doFinal(cipherText);
}
public static byte[] encrypt_CBC_Padding(byte[] key, byte[] iv, byte[] data)
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException,
InvalidAlgorithmParameterException {
Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_PADDING, Cipher.ENCRYPT_MODE, key, iv);
return cipher.doFinal(data);
}
public static byte[] decrypt_CBC_Padding(byte[] key, byte[] iv, byte[] cipherText)
throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
InvalidAlgorithmParameterException {
Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_PADDING, Cipher.DECRYPT_MODE, key, iv);
return cipher.doFinal(cipherText);
}
public static byte[] encrypt_CBC_NoPadding(byte[] key, byte[] iv, byte[] data)
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException,
InvalidAlgorithmParameterException {
Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_NOPADDING, Cipher.ENCRYPT_MODE, key, iv);
return cipher.doFinal(data);
}
public static byte[] decrypt_CBC_NoPadding(byte[] key, byte[] iv, byte[] cipherText)
throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
InvalidAlgorithmParameterException {
Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_NOPADDING, Cipher.DECRYPT_MODE, key, iv);
return cipher.doFinal(cipherText);
}
public static byte[] doCMac(byte[] key, byte[] data) throws NoSuchProviderException, NoSuchAlgorithmException,
InvalidKeyException {
Key keyObj = new SecretKeySpec(key, ALGORITHM_NAME);
return doMac("SM4-CMAC", keyObj, data);
}
public static byte[] doGMac(byte[] key, byte[] iv, int tagLength, byte[] data) {
org.bouncycastle.crypto.Mac mac = new GMac(new GCMBlockCipher(new SM4Engine()), tagLength * 8);
return doMac(mac, key, iv, data);
}
/**
* 默认使用PKCS7Padding/PKCS5Padding填充的CBCMAC
*
* @param key
* @param iv
* @param data
* @return
*/
public static byte[] doCBCMac(byte[] key, byte[] iv, byte[] data) {
SM4Engine engine = new SM4Engine();
org.bouncycastle.crypto.Mac mac = new CBCBlockCipherMac(engine, engine.getBlockSize() * 8, new PKCS7Padding());
return doMac(mac, key, iv, data);
}
/**
* @param key
* @param iv
* @param padding 可以传null传null表示NoPadding由调用方保证数据必须是BlockSize的整数倍
* @param data
* @return
* @throws Exception
*/
public static byte[] doCBCMac(byte[] key, byte[] iv, BlockCipherPadding padding, byte[] data) throws Exception {
SM4Engine engine = new SM4Engine();
if (padding == null) {
if (data.length % engine.getBlockSize() != 0) {
throw new Exception("if no padding, data length must be multiple of SM4 BlockSize");
}
}
org.bouncycastle.crypto.Mac mac = new CBCBlockCipherMac(engine, engine.getBlockSize() * 8, padding);
return doMac(mac, key, iv, data);
}
private static byte[] doMac(org.bouncycastle.crypto.Mac mac, byte[] key, byte[] iv, byte[] data) {
CipherParameters cipherParameters = new KeyParameter(key);
mac.init(new ParametersWithIV(cipherParameters, iv));
mac.update(data, 0, data.length);
byte[] result = new byte[mac.getMacSize()];
mac.doFinal(result, 0);
return result;
}
private static byte[] doMac(String algorithmName, Key key, byte[] data) throws NoSuchProviderException,
NoSuchAlgorithmException, InvalidKeyException {
Mac mac = Mac.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
mac.init(key);
mac.update(data);
return mac.doFinal();
}
private static Cipher generateECBCipher(String algorithmName, int mode, byte[] key)
throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
InvalidKeyException {
Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
cipher.init(mode, sm4Key);
return cipher;
}
private static Cipher generateCBCCipher(String algorithmName, int mode, byte[] key, byte[] iv)
throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException,
NoSuchProviderException, NoSuchPaddingException {
Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(mode, sm4Key, ivParameterSpec);
return cipher;
}
}

2
src/main/java/com/fr/password/tool/util/sm2/SM2Cipher.java → src/main/java/com/fr/password/tool/util/smx/SM2Cipher.java

@ -1,4 +1,4 @@
package com.fr.password.tool.util.sm2;
package com.fr.password.tool.util.smx;
public class SM2Cipher {
/**

2
src/main/java/com/fr/password/tool/util/sm2/SM2KeyPair.java → src/main/java/com/fr/password/tool/util/smx/SM2KeyPair.java

@ -1,4 +1,4 @@
package com.fr.password.tool.util.sm2;
package com.fr.password.tool.util.smx;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;

2
src/main/java/com/fr/password/tool/util/sm2/SM2Util.java → src/main/java/com/fr/password/tool/util/smx/SM2Util.java

@ -1,4 +1,4 @@
package com.fr.password.tool.util.sm2;
package com.fr.password.tool.util.smx;
import com.fr.password.tool.util.BCECUtil;
import com.fr.password.tool.util.GMBaseUtil;

2
src/main/java/com/fr/password/tool/util/sm2/SM3Util.java → src/main/java/com/fr/password/tool/util/smx/SM3Util.java

@ -1,4 +1,4 @@
package com.fr.password.tool.util.sm2;
package com.fr.password.tool.util.smx;
import com.fr.password.tool.util.GMBaseUtil;
import org.bouncycastle.crypto.digests.SM3Digest;

410
src/main/java/com/fr/password/tool/util/smx/SM4Util.java

@ -0,0 +1,410 @@
package com.fr.password.tool.util.smx;
import com.fr.password.tool.SecurityToolbox;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.security.SecureRandom;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 国密-对称加密
*/
public class SM4Util {
public static final int SM4_ENCRYPT = 1;
public static final int SM4_DECRYPT = 0;
public static final int DEFAULT_KEY_SIZE = 16;
private static long GET_ULONG_BE(byte[] b, int i) {
long n = (long) (b[i] & 0xff) << 24 | (long) ((b[i + 1] & 0xff) << 16) | (long) ((b[i + 2] & 0xff) << 8) | (long) (b[i + 3] & 0xff) & 0xffffffffL;
return n;
}
private static void PUT_ULONG_BE(long n, byte[] b, int i) {
b[i] = (byte) (int) (0xFF & n >> 24);
b[i + 1] = (byte) (int) (0xFF & n >> 16);
b[i + 2] = (byte) (int) (0xFF & n >> 8);
b[i + 3] = (byte) (int) (0xFF & n);
}
private static long SHL(long x, int n) {
return (x & 0xFFFFFFFF) << n;
}
private static long ROTL(long x, int n) {
return SHL(x, n) | x >> (32 - n);
}
private static void SWAP(long[] sk, int i) {
long t = sk[i];
sk[i] = sk[(31 - i)];
sk[(31 - i)] = t;
}
public static final byte[] SboxTable = {(byte) 0xd6, (byte) 0x90, (byte) 0xe9, (byte) 0xfe,
(byte) 0xcc, (byte) 0xe1, 0x3d, (byte) 0xb7, 0x16, (byte) 0xb6,
0x14, (byte) 0xc2, 0x28, (byte) 0xfb, 0x2c, 0x05, 0x2b, 0x67,
(byte) 0x9a, 0x76, 0x2a, (byte) 0xbe, 0x04, (byte) 0xc3,
(byte) 0xaa, 0x44, 0x13, 0x26, 0x49, (byte) 0x86, 0x06,
(byte) 0x99, (byte) 0x9c, 0x42, 0x50, (byte) 0xf4, (byte) 0x91,
(byte) 0xef, (byte) 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43,
(byte) 0xed, (byte) 0xcf, (byte) 0xac, 0x62, (byte) 0xe4,
(byte) 0xb3, 0x1c, (byte) 0xa9, (byte) 0xc9, 0x08, (byte) 0xe8,
(byte) 0x95, (byte) 0x80, (byte) 0xdf, (byte) 0x94, (byte) 0xfa,
0x75, (byte) 0x8f, 0x3f, (byte) 0xa6, 0x47, 0x07, (byte) 0xa7,
(byte) 0xfc, (byte) 0xf3, 0x73, 0x17, (byte) 0xba, (byte) 0x83,
0x59, 0x3c, 0x19, (byte) 0xe6, (byte) 0x85, 0x4f, (byte) 0xa8,
0x68, 0x6b, (byte) 0x81, (byte) 0xb2, 0x71, 0x64, (byte) 0xda,
(byte) 0x8b, (byte) 0xf8, (byte) 0xeb, 0x0f, 0x4b, 0x70, 0x56,
(byte) 0x9d, 0x35, 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, (byte) 0xd1,
(byte) 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, (byte) 0x87,
(byte) 0xd4, 0x00, 0x46, 0x57, (byte) 0x9f, (byte) 0xd3, 0x27,
0x52, 0x4c, 0x36, 0x02, (byte) 0xe7, (byte) 0xa0, (byte) 0xc4,
(byte) 0xc8, (byte) 0x9e, (byte) 0xea, (byte) 0xbf, (byte) 0x8a,
(byte) 0xd2, 0x40, (byte) 0xc7, 0x38, (byte) 0xb5, (byte) 0xa3,
(byte) 0xf7, (byte) 0xf2, (byte) 0xce, (byte) 0xf9, 0x61, 0x15,
(byte) 0xa1, (byte) 0xe0, (byte) 0xae, 0x5d, (byte) 0xa4,
(byte) 0x9b, 0x34, 0x1a, 0x55, (byte) 0xad, (byte) 0x93, 0x32,
0x30, (byte) 0xf5, (byte) 0x8c, (byte) 0xb1, (byte) 0xe3, 0x1d,
(byte) 0xf6, (byte) 0xe2, 0x2e, (byte) 0x82, 0x66, (byte) 0xca,
0x60, (byte) 0xc0, 0x29, 0x23, (byte) 0xab, 0x0d, 0x53, 0x4e, 0x6f,
(byte) 0xd5, (byte) 0xdb, 0x37, 0x45, (byte) 0xde, (byte) 0xfd,
(byte) 0x8e, 0x2f, 0x03, (byte) 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b,
0x51, (byte) 0x8d, 0x1b, (byte) 0xaf, (byte) 0x92, (byte) 0xbb,
(byte) 0xdd, (byte) 0xbc, 0x7f, 0x11, (byte) 0xd9, 0x5c, 0x41,
0x1f, 0x10, 0x5a, (byte) 0xd8, 0x0a, (byte) 0xc1, 0x31,
(byte) 0x88, (byte) 0xa5, (byte) 0xcd, 0x7b, (byte) 0xbd, 0x2d,
0x74, (byte) 0xd0, 0x12, (byte) 0xb8, (byte) 0xe5, (byte) 0xb4,
(byte) 0xb0, (byte) 0x89, 0x69, (byte) 0x97, 0x4a, 0x0c,
(byte) 0x96, 0x77, 0x7e, 0x65, (byte) 0xb9, (byte) 0xf1, 0x09,
(byte) 0xc5, 0x6e, (byte) 0xc6, (byte) 0x84, 0x18, (byte) 0xf0,
0x7d, (byte) 0xec, 0x3a, (byte) 0xdc, 0x4d, 0x20, 0x79,
(byte) 0xee, 0x5f, 0x3e, (byte) 0xd7, (byte) 0xcb, 0x39, 0x48};
public static final int[] FK = {0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc};
public static final int[] CK = {0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279};
public static String generateKey() {
SecureRandom secureRandom = new SecureRandom();
return ByteUtils.toHexString(secureRandom.generateSeed(DEFAULT_KEY_SIZE));
}
public static byte[] encryptData_ECB(String plainText, String secretKey) {
try {
SM4_Context ctx = new SM4_Context();
ctx.isPadding = true;
ctx.mode = SM4_ENCRYPT;
sm4_setkey_enc(ctx, ByteUtils.fromHexString(secretKey));
return sm4_crypt_ecb(ctx, plainText.getBytes("UTF-8"));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static byte[] decryptData_ECB(String cipherText, String secretKey) {
try {
byte[] encrypted = SecurityToolbox.getInstance().base642Byte(cipherText);
if (cipherText != null && cipherText.trim().length() > 0) {
Pattern p = Pattern.compile("\\s*|\t|\r|\n");
Matcher m = p.matcher(cipherText);
cipherText = m.replaceAll("");
}
SM4_Context ctx = new SM4_Context();
ctx.isPadding = true;
ctx.mode = SM4_DECRYPT;
sm4_setkey_dec(ctx, ByteUtils.fromHexString(secretKey));
return sm4_crypt_ecb(ctx, SecurityToolbox.getInstance().base642Byte(cipherText));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static byte[] encryptData_CBC(String plainText, String secretKey, String extraKey) {
try {
SM4_Context ctx = new SM4_Context();
ctx.isPadding = true;
ctx.mode = SM4_ENCRYPT;
sm4_setkey_enc(ctx, ByteUtils.fromHexString(secretKey));
byte[] encrypted = sm4_crypt_cbc(ctx, ByteUtils.fromHexString(extraKey), plainText.getBytes("UTF-8"));
return encrypted;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static byte[] decryptData_CBC(String cipherText, String secretKey, String extraKey) {
try {
byte[] encrypted = SecurityToolbox.getInstance().base642Byte(cipherText);
cipherText = SecurityToolbox.getInstance().byte2Base64(encrypted);
//cipherText = new BASE64Encoder().encode(encrypted);
if (cipherText != null && cipherText.trim().length() > 0) {
Pattern p = Pattern.compile("\\s*|\t|\r|\n");
Matcher m = p.matcher(cipherText);
cipherText = m.replaceAll("");
}
SM4_Context ctx = new SM4_Context();
ctx.isPadding = true;
ctx.mode = SM4_DECRYPT;
sm4_setkey_dec(ctx, ByteUtils.fromHexString(secretKey));
//byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, new BASE64Decoder().decodeBuffer(cipherText));
return sm4_crypt_cbc(ctx, ByteUtils.fromHexString(extraKey), SecurityToolbox.getInstance().base642Byte(cipherText));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private static byte sm4Sbox(byte inch) {
int i = inch & 0xFF;
byte retVal = SboxTable[i];
return retVal;
}
private static long sm4Lt(long ka) {
long bb = 0L;
long c = 0L;
byte[] a = new byte[4];
byte[] b = new byte[4];
PUT_ULONG_BE(ka, a, 0);
b[0] = sm4Sbox(a[0]);
b[1] = sm4Sbox(a[1]);
b[2] = sm4Sbox(a[2]);
b[3] = sm4Sbox(a[3]);
bb = GET_ULONG_BE(b, 0);
c = bb ^ ROTL(bb, 2) ^ ROTL(bb, 10) ^ ROTL(bb, 18) ^ ROTL(bb, 24);
return c;
}
private static long sm4F(long x0, long x1, long x2, long x3, long rk) {
return x0 ^ sm4Lt(x1 ^ x2 ^ x3 ^ rk);
}
private static long sm4CalciRK(long ka) {
long bb = 0L;
long rk = 0L;
byte[] a = new byte[4];
byte[] b = new byte[4];
PUT_ULONG_BE(ka, a, 0);
b[0] = sm4Sbox(a[0]);
b[1] = sm4Sbox(a[1]);
b[2] = sm4Sbox(a[2]);
b[3] = sm4Sbox(a[3]);
bb = GET_ULONG_BE(b, 0);
rk = bb ^ ROTL(bb, 13) ^ ROTL(bb, 23);
return rk;
}
private static void sm4_setkey(long[] SK, byte[] key) {
long[] MK = new long[4];
long[] k = new long[36];
int i = 0;
MK[0] = GET_ULONG_BE(key, 0);
MK[1] = GET_ULONG_BE(key, 4);
MK[2] = GET_ULONG_BE(key, 8);
MK[3] = GET_ULONG_BE(key, 12);
k[0] = MK[0] ^ (long) FK[0];
k[1] = MK[1] ^ (long) FK[1];
k[2] = MK[2] ^ (long) FK[2];
k[3] = MK[3] ^ (long) FK[3];
for (; i < 32; i++) {
k[(i + 4)] = (k[i] ^ sm4CalciRK(k[(i + 1)] ^ k[(i + 2)] ^ k[(i + 3)] ^ (long) CK[i]));
SK[i] = k[(i + 4)];
}
}
private static void sm4_one_round(long[] sk, byte[] input, byte[] output) {
int i = 0;
long[] ulbuf = new long[36];
ulbuf[0] = GET_ULONG_BE(input, 0);
ulbuf[1] = GET_ULONG_BE(input, 4);
ulbuf[2] = GET_ULONG_BE(input, 8);
ulbuf[3] = GET_ULONG_BE(input, 12);
while (i < 32) {
ulbuf[(i + 4)] = sm4F(ulbuf[i], ulbuf[(i + 1)], ulbuf[(i + 2)], ulbuf[(i + 3)], sk[i]);
i++;
}
PUT_ULONG_BE(ulbuf[35], output, 0);
PUT_ULONG_BE(ulbuf[34], output, 4);
PUT_ULONG_BE(ulbuf[33], output, 8);
PUT_ULONG_BE(ulbuf[32], output, 12);
}
//修改了填充模式
private static byte[] padding(byte[] input, int mode) {
if (input == null) {
return null;
}
byte[] ret = (byte[]) null;
if (mode == SM4_ENCRYPT) {
//填充:hex必须是32的整数倍填充 ,填充的是80 00 00 00
int p = 16 - input.length % 16;
String inputHex = ByteUtils.toHexString(input) + "80";
StringBuffer stringBuffer = new StringBuffer(inputHex);
for (int i = 0; i < p - 1; i++) {
stringBuffer.append("00");
}
ret = ByteUtils.fromHexString(stringBuffer.toString());
} else {
String inputHex = ByteUtils.toHexString(input);
int i = inputHex.lastIndexOf("80");
String substring = inputHex.substring(0, i);
ret = ByteUtils.fromHexString(substring);
}
return ret;
}
public static void sm4_setkey_enc(SM4_Context ctx, byte[] key) throws Exception {
if (ctx == null) {
throw new Exception("ctx is null!");
}
if (key == null || key.length != 16) {
throw new Exception("key error!");
}
ctx.mode = SM4_ENCRYPT;
sm4_setkey(ctx.sk, key);
}
public static void sm4_setkey_dec(SM4_Context ctx, byte[] key) throws Exception {
if (ctx == null) {
throw new Exception("ctx is null!");
}
if (key == null || key.length != 16) {
throw new Exception("key error!");
}
int i = 0;
ctx.mode = SM4_DECRYPT;
sm4_setkey(ctx.sk, key);
for (i = 0; i < 16; i++) {
SWAP(ctx.sk, i);
}
}
public static byte[] sm4_crypt_ecb(SM4_Context ctx, byte[] input) throws Exception {
if (input == null) {
throw new Exception("input is null!");
}
if ((ctx.isPadding) && (ctx.mode == SM4_ENCRYPT)) {
input = padding(input, SM4_ENCRYPT);
}
int length = input.length;
ByteArrayInputStream bins = new ByteArrayInputStream(input);
ByteArrayOutputStream bous = new ByteArrayOutputStream();
for (; length > 0; length -= 16) {
byte[] in = new byte[16];
byte[] out = new byte[16];
bins.read(in);
sm4_one_round(ctx.sk, in, out);
bous.write(out);
}
byte[] output = bous.toByteArray();
if (ctx.isPadding && ctx.mode == SM4_DECRYPT) {
output = padding(output, SM4_DECRYPT);
}
bins.close();
bous.close();
return output;
}
public static byte[] sm4_crypt_cbc(SM4_Context ctx, byte[] iv, byte[] input) throws Exception {
if (iv == null || iv.length != 16) {
throw new Exception("iv error!");
}
if (input == null) {
throw new Exception("input is null!");
}
if (ctx.isPadding && ctx.mode == SM4_ENCRYPT) {
input = padding(input, SM4_ENCRYPT);
}
int i = 0;
int length = input.length;
ByteArrayInputStream bins = new ByteArrayInputStream(input);
ByteArrayOutputStream bous = new ByteArrayOutputStream();
if (ctx.mode == SM4_ENCRYPT) {
for (; length > 0; length -= 16) {
byte[] in = new byte[16];
byte[] out = new byte[16];
byte[] out1 = new byte[16];
bins.read(in);
for (i = 0; i < 16; i++) {
out[i] = ((byte) (in[i] ^ iv[i]));
}
sm4_one_round(ctx.sk, out, out1);
System.arraycopy(out1, 0, iv, 0, 16);
bous.write(out1);
}
} else {
byte[] temp = new byte[16];
for (; length > 0; length -= 16) {
byte[] in = new byte[16];
byte[] out = new byte[16];
byte[] out1 = new byte[16];
bins.read(in);
System.arraycopy(in, 0, temp, 0, 16);
sm4_one_round(ctx.sk, in, out);
for (i = 0; i < 16; i++) {
out1[i] = ((byte) (out[i] ^ iv[i]));
}
System.arraycopy(temp, 0, iv, 0, 16);
bous.write(out1);
}
}
byte[] output = bous.toByteArray();
if (ctx.isPadding && ctx.mode == SM4_DECRYPT) {
output = padding(output, SM4_DECRYPT);
}
bins.close();
bous.close();
return output;
}
static class SM4_Context {
public int mode;
public long[] sk;
public boolean isPadding;
public SM4_Context() {
this.mode = 1;
this.isPadding = true;
this.sk = new long[32];
}
}
}

3
src/main/resources/application.properties

@ -0,0 +1,3 @@
server.port=10086
project.index=http://localhost:10086/encryption/for/test

147
src/main/resources/static/index.html

@ -0,0 +1,147 @@
<!DOCTYPE html>
<html lang="en">
<head>
<style>
#one {
float: left;
/*display: inline-block;*/
width: 50%;
height: 40%;
word-wrap: break-word;
/*// border-bottom: 3px solid red;*/
}
#two {
/*display: inline-block;*/
float: right;
position: relative;
width: 50%;
height: 40%;
}
</style>
<meta charset="UTF-8">
<title>测试系统加密</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/js-base64@3.5.2/base64.min.js"></script>
<script src="index.js"></script>
</head>
<body>
<div class="FGH delivery_day left col-md-4" id="one">
<div align="center">
<h2>RSA</h2>
<textarea rows="20" cols="80" id="rsa-textarea"></textarea>
<br>
<input type="button" id="rsa-encrypt" value="加密" style="width:120px;height:40px;font-size:20px;"
onclick="rsaEncrypt()">
<input type="button" id="rsa-decrypt" value="解密" style="width:120px;height:40px;font-size:20px;"
onclick="rsaDecrypt()">
<input type="file"
id="rsa-key" name="avatar" align="right"
accept=".txt">
</div>
<br>
<br>
<br>
<div align="center">
<h2>RSA-种子</h2>
<textarea rows="20" cols="80" id="rsa-textarea-with-seed"></textarea>
<br>
<input type="button" value="加密" style="width:120px;height:40px;font-size:20px;"
onclick="sm2EncryptWithSeed()">
<input type="button" value="解密" style="width:120px;height:40px;font-size:20px;"
onclick="rsaDecryptWithSeed()">
<input type="file" multiple
id="rsa-key-with-seed" name="avatar"
accept=".txt">
</div>
<br>
<br>
<br>
<div align="center">
<h2>国密</h2>
<textarea rows="20" cols="80" id="sm2-textarea"></textarea>
<br>
<input type="button" id="sm2-encrypt" value="加密" style="width:120px;height:40px;font-size:20px;"
onclick="sm2Encrypt()">
<input type="button" id="sm2-decrypt" value="解密" style="width:120px;height:40px;font-size:20px;"
onclick="sm2Decrypt()">
<input type="file"
id="sm2-key" name="avatar" align="right"
accept=".txt">
</div>
<br>
<br>
<br>
<div align="center">
<h2>国密-种子</h2>
<textarea rows="20" cols="80" name="sm2-textarea-with-seed"></textarea>
<br>
<input type="button" value="加密" style="width:120px;height:40px;font-size:20px;" onclick="sm2EncryptWithSeed()">
<input type="button" value="解密" style="width:120px;height:40px;font-size:20px;" onclick="sm2DecryptWithSeed()">
<input type="file" multiple
id="sm2-key-with-seed"
accept=".txt">
</div>
<br>
<br>
<br>
<div align="center">
<h2>商用国密</h2>
<textarea rows="20" cols="80" id="sm2-textarea-custom"></textarea>
<br>
<input type="button" id="sm2-encrypt-custom" value="加密" style="width:120px;height:40px;font-size:20px;"
onclick="sm2CustomEncrypt()">
<input type="button" id="sm2-decrypt-custom" value="解密" style="width:120px;height:40px;font-size:20px;"
onclick="sm2CustomDecrypt()">
</div>
<br>
<br>
<br>
</div>
<div class="FGH delivery_day left col-md-4" id="two">
<div align="center">
<h2>传输-AES</h2>
<textarea rows="20" cols="80" id="aes-textarea"></textarea>
<br>
<input type="button" value="加密" style="width:120px;height:40px;font-size:20px;" onclick="aesEncrypt()">
<input type="button" value="解密" style="width:120px;height:40px;font-size:20px;" onclick="aesDecrypt()">
<input type="text" id="aes-key" value="fOvwPYPkUmVYjnAO"/>
</div>
<br>
<br>
<br>
<div align="center">
<h2>传输-国密</h2>
<textarea rows="20" cols="80" id="sm4-textarea"></textarea>
<br>
<input type="button" value="加密" style="width:120px;height:40px;font-size:20px;" onclick="sm4Encrypt()">
<input type="button" value="解密" style="width:120px;height:40px;font-size:20px;" onclick="sm4Decrypt()">
<input type="text" id="sm4-key" value="edbfbd27db981534b1356d14f0e9bef9"/>
</div>
<br>
<br>
<br>
<div align="center">
<h2>SHA256</h2>
<textarea rows="20" cols="80" id="sha-textarea"></textarea>
<br>
<input type="button" value="加密" style="width:120px;height:40px;font-size:20px;"
onclick="sha()">
</div>
<br>
<br>
<br>
<div align="center">
<h2>国密-单向</h2>
<textarea rows="20" cols="80" id="sm3-textarea"></textarea>
<br>
<input type="button" value="加密" style="width:120px;height:40px;font-size:20px;"
onclick="sm3()">
</div>
<br>
<br>
<br>
</div>
</body>
</html>

289
src/main/resources/static/index.js

@ -0,0 +1,289 @@
// 存储-国密
function sm2Encrypt() {
const sm2Text = $('#sm2-textarea').val();
const files = $('#sm2-key').prop('files');
var key = undefined;
if (files.length > 0) {
var reader = new FileReader();
reader.readAsText(files[0], "UTF-8");
reader.onload = function (event) {
key = event.target.result;
$.ajax({
url: `/storage/encrypt/sm2?plainText=${Base64.encode(sm2Text)}&key=${Base64.encode(key)}`,
type: "GET",
cache: false,
success: function (data) {
$('#sm2-textarea').val(data)
},
})
}
}else{
$.ajax({
url: `/storage/encrypt/sm2?plainText=${Base64.encode(sm2Text)}&key=${Base64.encode(key)}`,
type: "GET",
cache: false,
success: function (data) {
$('#sm2-textarea').val(data)
},
})
}
}
function sm2Decrypt() {
const sm2Text = $('#sm2-textarea').val();
const files = $('#sm2-key').prop('files');
var key = undefined;
if (files.length > 0) {
var reader = new FileReader();
reader.readAsText(files[0], "UTF-8");
reader.onload = function (event) {
key = event.target.result;
$.ajax({
url: `/storage/decrypt/sm2?cipherText=${Base64.encode(sm2Text)}&key=${Base64.encode(key)}`,
type: "GET",
cache: false,
success: function (data) {
$('#sm2-textarea').val(data)
},
})
}
}else{
$.ajax({
url: `/storage/decrypt/sm2?cipherText=${Base64.encode(sm2Text)}&key=${Base64.encode(key)}`,
type: "GET",
cache: false,
success: function (data) {
$('#sm2-textarea').val(data)
},
})
}
}
function sm2EncryptWithSeed() {
const sm2Text = $('#sm2-textarea-with-seed').val();
const files = $('#sm2-key-with-seed').prop('files');
if (files.length == 3) {
// 获取三个种子文件的内容
var reader = new FileReader();
reader.readAsText(files[0], "UTF-8");
reader.onload = function (event) {
let key = event.target.result;
let seed1 = "qwe";
let seed2 = "qwe123";
let seed3 = "qwe123rty";
$.ajax({
url: `/storage/encrypt/sm2/seed?plainText=${sm2Text}&seed1=${Base64.encode(seed1)}&seed2=${Base64.encode(seed2)}&seed3=${Base64.encode(seed3)}`,
type: "GET",
cache: false,
success: function (data) {
$('#sm2-textarea').val(data)
},
})
}
}
}
function sm2DecryptWithSeed() {
const sm2Text = $('#sm2-textarea-with-seed').val();
const files = $('#sm2-key-with-seed').prop('files');
if (files.length == 3) {
var reader = new FileReader();
reader.readAsText(files[0], "UTF-8");
reader.onload = function (event) {
let key = event.target.result;
let seed1 = "qwe";d
let seed2 = "qwe123";
let seed3 = "qwe123rty";
$.ajax({
url: `/storage/decrypt/sm2/seed?cipherText=${sm2Text}&seed1=${Base64.encode(seed1)}&seed2=${Base64.encode(seed2)}&seed3=${Base64.encode(seed3)}`,
type: "GET",
cache: false,
success: function (data) {
$('#sm2-textarea').val(data)
},
})
}
}
}
// 存储rsa
function rsaEncrypt() {
const rsaText = $('#rsa-textarea').val();
const files = $('#rsa-key').prop('files');
var key = undefined;
if (files.length > 0) {
var reader = new FileReader();
reader.readAsText(files[0], "UTF-8");
reader.onload = function (event) {
key = event.target.result;
$.ajax({
url: `/storage/encrypt/rsa?plainText=${Base64.encode(rsaText)}&key=${Base64.encode(key)}`,
type: "GET",
cache: false,
success: function (data) {
$('#rsa-textarea').val(data)
},
})
}
}else{
$.ajax({
url: `/storage/encrypt/rsa?plainText=${Base64.encode(rsaText)}&key=${Base64.encode(key)}`,
type: "GET",
cache: false,
success: function (data) {
$('#rsa-textarea').val(data)
},
})
}
}
function rsaDecrypt() {
const rsaText = $('#rsa-textarea').val();
const files = $('#rsa-key').prop('files');
var key = undefined;
if (files.length > 0) {
var reader = new FileReader();
reader.readAsText(files[0], "UTF-8");
reader.onload = function (event) {
key = event.target.result;
$.ajax({
url: `/storage/decrypt/rsa?cipherText=${Base64.encode(rsaText)}&key=${Base64.encode(key)}`,
type: "GET",
cache: false,
success: function (data) {
$('#rsa-textarea').val(data)
},
})
}
}else{
$.ajax({
url: `/storage/decrypt/rsa?cipherText=${Base64.encode(rsaText)}&key=${Base64.encode(key)}`,
type: "GET",
cache: false,
success: function (data) {
$('#rsa-textarea').val(data)
},
})
}
}
// 传输加密
function aesEncrypt() {
const aesText = $('#aes-textarea').val();
const key = $('#aes-key').val();
console.log(key)
$.ajax({
url: `/transmission/encrypt/aes?plainText=${Base64.encode(aesText)}&key=${Base64.encode(key)}`,
type: "GET",
cache: false,
success: function (data) {
$('#aes-textarea').val(data)
},
})
}
function aesDecrypt() {
const aesText = $('#aes-textarea').val();
const key = $('#aes-key').val()
$.ajax({
url: `/transmission/decrypt/aes?cipherText=${Base64.encode(aesText)}&key=${Base64.encode(key)}`,
type: "GET",
cache: false,
success: function (data) {
$('#aes-textarea').val(data)
},
})
}
function sm4Encrypt() {
const sm4Text = $('#sm4-textarea').val();
const key = $('#sm4-key').val();
console.log(key)
$.ajax({
url: `/transmission/encrypt/sm4?plainText=${Base64.encode(sm4Text)}&key=${Base64.encode(key)}`,
type: "GET",
cache: false,
success: function (data) {
$('#sm4-textarea').val(data)
},
})
}
function sm4Decrypt() {
const sm4Text = $('#sm4-textarea').val();
const key = $('#sm4-key').val()
$.ajax({
url: `/transmission/decrypt/sm4?cipherText=${Base64.encode(sm4Text)}&key=${Base64.encode(key)}`,
type: "GET",
cache: false,
success: function (data) {
$('#sm4-textarea').val(data)
},
})
}
// 自定义的加密方式
function sm2CustomEncrypt() {
const sm2Text = $('#sm2-textarea-custom').val();
$.ajax({
url: `/storage/encrypt/sm2/custom?plainText=${Base64.encode(sm2Text)}`,
type: "GET",
cache: false,
success: function (data) {
$('#sm2-textarea-custom').val(data)
},
})
}
function sm2CustomDecrypt() {
const sm2Text = $('#sm2-textarea-custom').val();
$.ajax({
url: `/storage/decrypt/sm2/custom?cipherText=${Base64.encode(sm2Text)}`,
type: "GET",
cache: false,
success: function (data) {
$('#sm2-textarea-custom').val(data)
},
})
}
function sha() {
const sm2Text = $('#sha-textarea').val();
$.ajax({
url: `/password/encrypt/sha?plainText=${Base64.encode(sm2Text)}`,
type: "GET",
cache: false,
success: function (data) {
$('#sha-textarea').val(data)
},
})
}
function sm3() {
const sm2Text = $('#sm3-textarea').val();
$.ajax({
url: `/password/encrypt/sm3?plainText=${Base64.encode(sm2Text)}`,
type: "GET",
cache: false,
success: function (data) {
$('#sm3-textarea').val(data)
},
})
}

1
src/test/java/com/fr/password/tool/keys/RSAKeysHandlerTest.java

@ -22,7 +22,6 @@ public class RSAKeysHandlerTest extends TestCase {
}
public void testGenerate() {
}
public void testLoadFromFile() throws IOException {

11
src/test/java/com/fr/password/tool/keys/SM2KeysHandlerTest.java

@ -1,8 +1,9 @@
package com.fr.password.tool.keys;
import com.fr.password.tool.util.BCECUtil;
import com.fr.password.tool.util.EncodeUtil;
import com.fr.password.tool.util.sm2.SM2KeyPair;
import com.fr.password.tool.util.sm2.SM2Util;
import com.fr.password.tool.util.smx.SM2KeyPair;
import com.fr.password.tool.util.smx.SM2Util;
import junit.framework.TestCase;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
@ -30,6 +31,12 @@ public class SM2KeysHandlerTest extends TestCase {
ECPublicKeyParameters publicKeyParameters = SM2KeysHandler.getInstance().string2PublicKey(publicLey, privateKey);
Assert.assertEquals(privateKeyParameters.getD(), sm2KeyPair.getPrivateKeyParameters().getD());
Assert.assertEquals(EncodeUtil.byte2HexString(publicKeyParameters.getQ().getEncoded(false)), EncodeUtil.byte2HexString(sm2KeyPair.getPublicKeyParameters().getQ().getEncoded(false)));
String systemPrivate = "MzA4MjAxNTEwMjAxMDEwNDIwYzQxYTMyYzRhOWMwMTFhYmE0Yzk2NjA4YjUwMDA1NzllNzA2ZmRmZDA2NDE4NjljNmRjNGJkNDY3MmQ1YWI4ZmEwODFlMzMwODFlMDAyMDEwMTMwMmMwNjA3MmE4NjQ4Y2UzZDAxMDEwMjIxMDBmZmZmZmZmZWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmMDAwMDAwMDBmZmZmZmZmZmZmZmZmZmZmMzA0NDA0MjBmZmZmZmZmZWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmMDAwMDAwMDBmZmZmZmZmZmZmZmZmZmZjMDQyMDI4ZTlmYTllOWQ5ZjVlMzQ0ZDVhOWU0YmNmNjUwOWE3ZjM5Nzg5ZjUxNWFiOGY5MmRkYmNiZDQxNGQ5NDBlOTMwNDQxMDQzMmM0YWUyYzFmMTk4MTE5NWY5OTA0NDY2YTM5Yzk5NDhmZTMwYmJmZjI2NjBiZTE3MTVhNDU4OTMzNGM3NGM3YmMzNzM2YTJmNGY2Nzc5YzU5YmRjZWUzNmI2OTIxNTNkMGE5ODc3Y2M2MmE0NzQwMDJkZjMyZTUyMTM5ZjBhMDAyMjEwMGZmZmZmZmZlZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmNzIwM2RmNmIyMWM2MDUyYjUzYmJmNDA5MzlkNTQxMjMwMjAxMDFhMTQ0MDM0MjAwMDQ4NjljY2VkZGM0YzI1ZmMzOGQ3MjZkM2QxOTYyZDgzYjkyMTM4ZmU1MWRlNDE3NzZjOTg1ODc5NGJmZDEwOWNkYTBjOWIwNGNkMzY4MDk3YTQ4ZDk0ODhhNzhmMjRiODA2ODA1NWYzNWMyOTk2OWUxZmFkODQ4MTY3MzVjNDUyNQ==";
ECPrivateKeyParameters pri = SM2KeysHandler.getInstance().string2PrivateKey(systemPrivate);
ECPublicKeyParameters pub = BCECUtil.buildECPublicKeyByPrivateKey(pri);
System.out.println(SM2KeysHandler.getInstance().publicKey2String(pub,pri));
}
public void testLoadFromFile() throws IOException, InvalidKeySpecException, NoSuchAlgorithmException, NoSuchProviderException, InvalidCipherTextException {

10
src/test/java/com/fr/password/tool/util/smx/SM2UtilTest.java

@ -0,0 +1,10 @@
package com.fr.password.tool.util.smx;
import junit.framework.TestCase;
public class SM2UtilTest extends TestCase {
public void testCFCA() {
}
}
Loading…
Cancel
Save