一、引入java
默认只要在 aardio 中调用
import java;
就会自动搜索系统可用的 JRE,如果没有找到 JRE,会自动导入 java.jre.v8 扩展库,并自动安装 OpenJDK JRE v8 。
注:如果系统已经安装了java6,就会用系统自带的java6,而不会自动安装OpenJDK JRE v8。
项目经验:项目开发过程中就遇到这样的问题:由于java工具类是用java8编译的,在没有安装java6的电脑,aardio调用java是正常的,因为会自动安装java8。但是在安装了java6的电脑,aardio就无法调用java,因为系统已经存在java6了,就不会自动安装java8,由于用java8编译成的class文件中部分代码(如Base64在java6中没有)在java6中无法运行,导致aardio无法调用java,从而导致插件无法使用。后来将工具类用java6编译后,就能正常使用了。
如果您希望发布的软件自带 Java 运行时,或者指定 JRE 的版本,只要在 aardio 中导入其他版本 JRE 的扩展库就可以,例如运行
import java.jre.v8ora
就可以自动绑定 Oracle Java 8 运行时,软件运行会自动查找用户电脑上符合要求的 JRE,如果没有找到会全自动地安装和部署好,开发者要做的,仅仅就是写几句代码,把 EXE 简单地分发给用户就可以了。
二、调用java案例
import java; var jvm = ..java(); // 创建 Java 虚拟机 var RSA = jvm.import("aardio.util.RSAUtils"); // 导入 Java 类 return RSA .encryptByPublicKey(..web.json.stringify(sourceData),publicKey);
注意:由于class文件中的encryptByPublicKey为静态方法,故不用实例化RSA,直接用RSA调用encryptByPublicKey方法。当然也可以先实例化,在调用
import java; var jvm = ..java(); // 创建 Java 虚拟机 var RSA = jvm.import("aardio.util.RSAUtils"); // 导入 Java 类 var rsa = RSA(); // 实例化 return rsa .encryptByPublicKey(..web.json.stringify(sourceData),publicKey);
RSAUtils.class文件如下:
package aardio.util; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.xml.bind.DatatypeConverter; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.Charset; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; public class RSAUtils { // RSA 最大加密明文大小 private static final int MAX_ENCRYPT_BLOCK = 117; // RSA 最大解密密文大小 private static final int MAX_DECRYPT_BLOCK = 128; /** * 密钥长度 于原文长度对应 以及越长速度越慢 */ private final static int KEY_SIZE = 1024; private final static String PUBLIC_KEY ="PUBLIC_KEY"; private final static String PRIVATE_KEY ="PRIVATE_KEY"; /** * 用于封装随机产生的公钥与私钥 */ private static Map<String, String> keyMap = new HashMap<String,String>(); /** * 随机生成密钥对 */ public static Map<String,String> genKeyPair() throws NoSuchAlgorithmException { // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); // 初始化密钥对生成器 keyPairGen.initialize(KEY_SIZE, new SecureRandom()); // 生成一个密钥对,保存在keyPair中 KeyPair keyPair = keyPairGen.generateKeyPair(); // 得到私钥 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到公钥 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); String publicKeyString = DatatypeConverter.printBase64Binary(publicKey.getEncoded()); // String publicKeyString = Base64.getEncoder().encodeToString(publicKey.getEncoded()); // 得到私钥字符串 String privateKeyString = DatatypeConverter.printBase64Binary(privateKey.getEncoded()); // String privateKeyString = Base64.getEncoder().encodeToString(privateKey.getEncoded()); // 将公钥和私钥保存到Map keyMap.put(aardio.util.RSAUtils.PUBLIC_KEY, publicKeyString); // 将私钥和私钥保存到Map keyMap.put(aardio.util.RSAUtils.PRIVATE_KEY, privateKeyString); return keyMap; } /** * 得到公钥 * @return */ public static String getPublicKey(){ return keyMap.get(aardio.util.RSAUtils.PUBLIC_KEY); } /** * 得到私钥 * @return */ public static String getPrivateKey(){ return keyMap.get(aardio.util.RSAUtils.PRIVATE_KEY); } public static String encryptByPublicKey(String sourceData, String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException { byte[] dataBytes = sourceData.getBytes(Charset.forName("UTF-8")); // byte[] keyBytes = Base64.getDecoder().decode(publicKey); byte[] keyBytes = DatatypeConverter.parseBase64Binary(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); Key pubK = keyFactory.generatePublic(x509KeySpec); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, pubK); int inputLen = dataBytes.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(dataBytes, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(dataBytes, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } // String encryptData = Base64.getEncoder().encodeToString(out.toByteArray()); String encryptData = DatatypeConverter.printBase64Binary(out.toByteArray()); out.close(); return encryptData; } public static String decryptByPublicKey(String encryptData, String pubKey) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException { // byte[] sourceBytes = Base64.getDecoder().decode(encryptData); byte[] sourceBytes = DatatypeConverter.parseBase64Binary(encryptData); // byte[] keyBytes = Base64.getDecoder().decode(pubKey); byte[] keyBytes = DatatypeConverter.parseBase64Binary(pubKey); X509EncodedKeySpec x50KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); Key pubK = keyFactory.generatePublic(x50KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, pubK); int inputLen = sourceBytes.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(sourceBytes, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(sourceBytes, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } String decryptedData = out.toString("UTF-8"); out.close(); return decryptedData; } }View Code
注意:package的包为aardio.util,而不是IDEA中的包路径。
RSAUtils.class在aardio中的包结构如下:
注意:如果系统中已经安装了java6,那么java的工具类需要用java6进行编译。
注意:如果java工具类中要引入其他包,如下MD5Utils.java引入了
import org.apache.commons.codec.binary.Hex;
故需要将commons-codec-1.15.jar放到aardio.util目录下
MD5Utils.java如下所示:
package aardio.util; import org.apache.commons.codec.binary.Hex; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Random; public class MD5Utils { public static Random random = new SecureRandom(); /** * MD5加密 * @param str 待加密数据项 * @return */ public static String getMD5(String str) { MessageDigest messageDigest = null; try { messageDigest = MessageDigest.getInstance("MD5"); messageDigest.reset(); messageDigest.update(str.getBytes("UTF-8")); } catch (NoSuchAlgorithmException e) { System.out.println("NoSuchAlgorithmException caught!"); System.exit(-1); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } byte[] byteArray = messageDigest.digest(); StringBuffer md5StrBuff = new StringBuffer(); for (int i = 0; i < byteArray.length; i++) { if (Integer.toHexString(0xFF & byteArray[i]).length() == 1) { md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i])); }else { md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i])); } } return md5StrBuff.toString(); } /** * 不加盐验证md5加密结果 * @param password 原始密码 * @param md5str 加密后的值 * @return * @throws Exception */ public static boolean getVerifyMD5(String password, String md5str) throws Exception{ return getMD5(password).equals(md5str); } /** * 加盐MD5算法 * @param password * @return */ public static String getSaltMD5(String password) throws Exception{ StringBuilder sb = new StringBuilder(16); sb.append(random.nextInt(99999999)).append(random.nextInt(99999999)); int len = sb.length(); if(len < 18){ int diffLen = 16 - len; for(int i = 0; i < diffLen; i ++){ sb.append(0); } } String salt = sb.toString(); password = md5Hex(password + salt); char[] cs = new char[48]; for (int i = 0; i < 48; i += 3) { cs[i] = password.charAt(i / 3 * 2); char c = salt.charAt(i / 3); cs[i + 1] = c; cs[i + 2] = password.charAt(i / 3 * 2 + 1); } return String.valueOf(cs); } /** * 使用Apache的Hex类实现Hex(16进制字符串和)和字节数组的互转 * @param str 原明文字符串 * @return 转换后的字符 */ private static String md5Hex(String str) throws Exception{ MessageDigest md = MessageDigest.getInstance("MD5"); byte[] digest = md.digest(str.getBytes()); return new String(new Hex().encode(digest)); } /** * 验证加盐后是否和原文一致 * @param password 原始密码 * @param md5str md5后值 * @return */ public static boolean getSaltverifyMD5(String password, String md5str) throws Exception{ char[] cs1 = new char[32]; char[] cs2 = new char[16]; for (int i = 0; i < 48; i += 3) { cs1[i / 3 * 2] = md5str.charAt(i); cs1[i / 3 * 2 + 1] = md5str.charAt(i + 2); cs2[i / 3] = md5str.charAt(i + 1); } String salt = new String(cs2); return md5Hex(password + salt).equals(String.valueOf(cs1)); } /** * 获取文件的md5值 ,有可能不是32位 * @param filePath 文件路径 * @return * @throws FileNotFoundException */ public static String md5HashCode(String filePath) throws FileNotFoundException{ FileInputStream fis = new FileInputStream(filePath); return md5HashCode(fis); } /** * 保证文件的MD5值为32位 * @param filePath 文件路径 * @return * @throws FileNotFoundException */ public static String md5HashCode32(String filePath) throws FileNotFoundException{ FileInputStream fis = new FileInputStream(filePath); return md5HashCode32(fis); } /** * java获取文件的md5值 * @param fis 输入流 * @return */ public static String md5HashCode(InputStream fis) { try { //拿到一个MD5转换器,如果想使用SHA-1或SHA-256,则传入SHA-1,SHA-256 MessageDigest md = MessageDigest.getInstance("MD5"); //分多次将一个文件读入,对于大型文件而言,比较推荐这种方式,占用内存比较少。 byte[] buffer = new byte[1024]; int length = -1; while ((length = fis.read(buffer, 0, 1024)) != -1) { md.update(buffer, 0, length); } fis.close(); //转换并返回包含16个元素字节数组,返回数值范围为-128到127 byte[] md5Bytes = md.digest(); BigInteger bigInt = new BigInteger(1, md5Bytes);//1代表绝对值 return bigInt.toString(16);//转换为16进制 } catch (Exception e) { e.printStackTrace(); return ""; } } /** * java计算文件32位md5值 * @param fis 输入流 * @return */ public static String md5HashCode32(InputStream fis) { try { //拿到一个MD5转换器,如果想使用SHA-1或SHA-256,则传入SHA-1,SHA-256 MessageDigest md = MessageDigest.getInstance("MD5"); //分多次将一个文件读入,对于大型文件而言,比较推荐这种方式,占用内存比较少。 byte[] buffer = new byte[1024]; int length = -1; while ((length = fis.read(buffer, 0, 1024)) != -1) { md.update(buffer, 0, length); } fis.close(); //转换并返回包含16个元素字节数组,返回数值范围为-128到127 byte[] md5Bytes = md.digest(); StringBuffer hexValue = new StringBuffer(); for (int i = 0; i < md5Bytes.length; i++) { int val = ((int) md5Bytes[i]) & 0xff;//解释参见最下方 if (val < 16) { /** * 如果小于16,那么val值的16进制形式必然为一位, * 因为十进制0,1...9,10,11,12,13,14,15 对应的 16进制为 0,1...9,a,b,c,d,e,f; * 此处高位补0。 */ hexValue.append("0"); } //这里借助了Integer类的方法实现16进制的转换 hexValue.append(Integer.toHexString(val)); } return hexValue.toString(); } catch (Exception e) { e.printStackTrace(); return ""; } } public static void main(String[] args) { System.out.println(getMD5("crpts123@")); } }View Code
标签:调用,return,String,java,aardio,static,new,import From: https://www.cnblogs.com/zwh0910/p/17792978.html