这里写自定义目录标题

  • xjar安全加密运行工具
    • 创建项目
    • 编写代码
    • idea将maven项目打包成可运行的jar包
    • 运行加密jar文件
    • centos 安装go
    • springboot项目集成xjar 加密工具
      • 打包运行
    • 实际部署项目为例测试:
    • 通过反编译工具查看加密的jar包

xjar安全加密运行工具

GitHub: https://github.com/core-lib/xjar

Spring Boot JAR 安全加密运行工具, 同时支持的原生JAR.
基于对JAR包内资源的加密以及拓展ClassLoader来构建的一套程序加密启动, 动态解密运行的方案, 避免源码泄露以及反编译.

功能特性
无代码侵入, 只需要把编译好的JAR包通过工具加密即可.
完全内存解密, 降低源码以及字节码泄露或反编译的风险.
支持所有JDK内置加解密算法.
可选择需要加解密的字节码或其他资源文件.
支持Maven插件, 加密更加便捷.
动态生成Go启动器, 保护密码不泄露.

创建项目

源码: https://gitee.com/starsky20/starsky-xjar.git

1、使用idea创建一个java项目,然后引入xjar需要的jar包。
打开idea, 点击菜单 File-》new-》Project-》选择maven项目-》


创建完成如下:

编写代码

pom.xml 引入xjar依赖包:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>demo-xjar</artifactId><version>1.0-SNAPSHOT</version><dependencies><!-- 添加 XJar 依赖 --><dependency><groupId>com.github.core-lib</groupId><artifactId>xjar</artifactId><version>4.0.2</version><!-- <scope>test</scope> --></dependency><dependency><groupId>commons-lang</groupId><artifactId>commons-lang</artifactId><version>2.5</version></dependency></dependencies><!-- 设置 jitpack.io 仓库 --><repositories><repository><id>jitpack.io</id><url>https://jitpack.io</url></repository></repositories></project>

2、编写代码,生成加密文件
参考文档:https://www.cnblogs.com/-flq/p/14297274.html
package com.starsky.xjar;

import io.xjar.XKit;
import io.xjar.boot.XBoot;
import io.xjar.key.XKey;
import org.apache.commons.lang.StringUtils;import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Date;/*** @desc:xjar 加密工具,针对java开发项目jar包进行加密,jar加密后,大小会翻倍,同时swagger无法访问,接口暂时未发现问题* @author: wangsh* @time: 2021/4/15 9:34*/
public class XjarEncryUtil {public static void main(String[] args) {createJFrame();}/*** 创建面板,这个类似于 HTML 的 div 标签,我们可以创建多个面板并在 JFrame 中指定位置,面板中我们可以添加文本字段,按钮及其他组件。*/public static void createJFrame() {// 创建 JFrame 实例JFrame frame = new JFrame("XJar加密,防止反编译");// 设置窗口大小frame.setSize(600, 400);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//创建面板,这个类似于 HTML 的 div 标签,可以创建多个面板并在 JFrame 中指定位置,// 面板中可以添加文本字段,按钮及其他组件。JPanel panel = new JPanel();// 添加面板frame.add(panel);//调用用户定义的方法并添加组件到面板addComponents(panel);// 设置界面可见frame.setVisible(true);}/*** 调用用户定义的方法并添加组件到面板*/private static void addComponents(JPanel panel) {//布局部分我们这边不多做介绍,这边设置布局为 nullpanel.setLayout(null);// 创建 需要加密的jar JLabelJLabel fromLabel = new JLabel("选择加密的jar:");fromLabel.setBounds(10, 20, 120, 30);panel.add(fromLabel);//用于记录未加密jar的文本域final JTextField fromText = new JTextField(20);fromText.setBounds(100, 20, 300, 30);panel.add(fromText);// 创建选择按钮JButton fromButton = new JButton("选择");fromButton.setBounds(420, 20, 80, 30);panel.add(fromButton);// 加密后jar要保存的位置JLabel toLabel = new JLabel("选择保存位置:");toLabel.setBounds(10, 50, 120, 30);panel.add(toLabel);//文本域用于记录保存路径final JTextField toText = new JTextField(20);toText.setBounds(100, 50, 300, 30);panel.add(toText);// 创建选择按钮JButton toButton = new JButton("选择");toButton.setBounds(420, 50, 80, 30);panel.add(toButton);// 输入密码的文本域JLabel passwordLabel = new JLabel("加密密码:");passwordLabel.setBounds(10, 80, 80, 30);panel.add(passwordLabel);//这个类似用于输入的文本域,但是输入的信息会以点号代替,用于包含密码的安全性final JPasswordField passwordText = new JPasswordField(20);passwordText.setBounds(100, 80, 300, 30);panel.add(passwordText);// 创建开始按钮JButton startButton = new JButton("加密");startButton.setBounds(100, 110, 80, 30);panel.add(startButton);// 创建开始按钮JButton endButton = new JButton("解密");endButton.setBounds(200, 110, 80, 30);panel.add(endButton);//日志显示框final JTextArea textArea = new JTextArea("");textArea.setBounds(10, 150, 550, 150);textArea.setLineWrap(true);textArea.setWrapStyleWord(true);panel.add(textArea);//选择jar按钮监听事件fromButton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {  //按钮点击事件JFileChooser chooser = new JFileChooser();             //设置选择器chooser.setMultiSelectionEnabled(false);             //设为单选int returnVal = chooser.showOpenDialog(null);        //是否打开文件选择框if (returnVal == JFileChooser.APPROVE_OPTION) {          //如果符合文件类型String filepath = chooser.getSelectedFile().getAbsolutePath();      //获取绝对路径if (!".jar".equals(filepath.substring(filepath.length() - 4))) {JOptionPane.showMessageDialog(null, "文件格式不正确,请选择jar文件!", "文件格式错误", JOptionPane.ERROR_MESSAGE);} else {fromText.setText(filepath);}System.out.println(filepath);}}});//选择加密后jar保存路径按钮监听事件toButton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {  //按钮点击事件JFileChooser chooser = new JFileChooser();             //设置选择器chooser.setMultiSelectionEnabled(false);             //设为单选chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); //设置只选目录chooser.setDialogTitle("选择加密后jar保存位置");int returnVal = chooser.showOpenDialog(null);        //是否打开文件选择框if (returnVal == JFileChooser.APPROVE_OPTION) {          //如果符合文件类型String filepath = chooser.getSelectedFile().getAbsolutePath();      //获取绝对路径toText.setText(filepath);System.out.println(filepath);}}});//选择开始径按钮的监听事件startButton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {String fromJarPath = fromText.getText();String toJarPath = toText.getText() + "\\encrypt" + getNowDateTime() + ".jar";String password = new String(passwordText.getPassword());System.out.println("fromJarPath=" + fromJarPath);System.out.println("toJarPath=" + toJarPath);System.out.println("password=" + password);if (StringUtils.isEmpty(fromJarPath)) {JOptionPane.showMessageDialog(null, "jar文件不能为空!", "jar文件不能为空!", JOptionPane.ERROR_MESSAGE);return;}if (StringUtils.isEmpty(toJarPath)) {JOptionPane.showMessageDialog(null, "保存路径不能为空!", "保存路径不能为空!", JOptionPane.ERROR_MESSAGE);return;}if (StringUtils.isEmpty(toJarPath)) {JOptionPane.showMessageDialog(null, "请输入加密的密码!", "密码不能为空!", JOptionPane.ERROR_MESSAGE);return;}//打印输入日志StringBuilder builder = new StringBuilder();builder.append("fromJarPath=" + fromJarPath + "\n");builder.append("toJarPath=" + toJarPath + "\n");textArea.setText(builder.toString());//开始加密文件encryptJar(fromJarPath, toJarPath, password);textArea.append("jar加密成功!\n请测试接口是否正常(注意:Swagger不可用)");}});//选择开始径按钮的监听事件endButton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {String fromJarPath = fromText.getText();String toJarPath = toText.getText() + "\\encrypt" + getNowDateTime() + ".jar";String password = new String(passwordText.getPassword());System.out.println("fromJarPath=" + fromJarPath);System.out.println("toJarPath=" + toJarPath);System.out.println("password=" + password);if (StringUtils.isEmpty(fromJarPath)) {JOptionPane.showMessageDialog(null, "jar文件不能为空!", "jar文件不能为空!", JOptionPane.ERROR_MESSAGE);return;}if (StringUtils.isEmpty(toJarPath)) {JOptionPane.showMessageDialog(null, "保存路径不能为空!", "保存路径不能为空!", JOptionPane.ERROR_MESSAGE);return;}if (StringUtils.isEmpty(toJarPath)) {JOptionPane.showMessageDialog(null, "请输入加密的密码!", "密码不能为空!", JOptionPane.ERROR_MESSAGE);return;}//打印输入日志StringBuilder builder = new StringBuilder();builder.append("fromJarPath=" + fromJarPath + "\n");builder.append("toJarPath=" + toJarPath + "\n");textArea.setText(builder.toString());//开始加密文件decryptJar(fromJarPath, toJarPath, password);textArea.append("jar加密成功!\n请测试接口是否正常(注意:Swagger不可用)");}});}/*** 获取当前格式化时间的方法*/private static String getNowDateTime() {String dateNow = "";SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");Date date = new Date();dateNow = format.format(date);return dateNow;}/*** jar包加密,防止反编译* 此编译方式在运行jar包时需要输入密码* 运行方式一 :* // 命令行运行JAR 然后在提示输入密码的时候输入密码后按回车即可正常启动* java -jar /path/to/encrypted.jar* 运行方式二:* // 也可以通过传参的方式直接启动,不太推荐这种方式,因为泄露的可能性更大!* java -jar /path/to/encrypted.jar --xjar.password=PASSWORD* 运行方式三:* // 对于 nohup 或 javaw 这种后台启动方式,无法使用控制台来输入密码,推荐使用指定密钥文件的方式启动* nohup java -jar /path/to/encrypted.jar --xjar.keyfile=/path/to/xjar.key* xjar.key 文件说明:* 格式:* password: PASSWORD* algorithm: ALGORITHM* keysize: KEYSIZE* ivsize: IVSIZE* hold: HOLD* 参数说明:* password    密码  无   密码字符串* algorithm   密钥算法    AES     支持JDK所有内置算法,如AES / DES ...* keysize     密钥长度    128     根据不同的算法选取不同的密钥长度。* ivsize  向量长度    128     根据不同的算法选取不同的向量长度。* hold    是否保留    false   读取后是否保留密钥文件。** @param fromJarPath 需要加密的jar* @param toJarPath   加密后的jar* @param password    加密密码*/public static void encryptJar(String fromJarPath, String toJarPath, String password) {try {// Spring-Boot Jar包加密XKey xKey = XKit.key(password);XBoot.encrypt(fromJarPath, toJarPath, xKey);} catch (Exception e) {e.printStackTrace();}}/*** jar包解密** @param fromJarPath 已通过Xjar加密的jar文件路径* @param toJarPath   解密后的jar文件* @param password    密码*/public static void decryptJar(String fromJarPath, String toJarPath, String password) {try {XKey xKey = XKit.key(password);XBoot.decrypt(fromJarPath, toJarPath, xKey);} catch (Exception e) {e.printStackTrace();}}}

以上编写完成后可以直接运行main,结果如下:

以上是通过工具直接运行结果,如果我们需要将项目放在其他地方使用,很不方便,故需要将项目打包成jar包运行,下面介绍通过idea将maven项目打包成可运行的jar包。

idea将maven项目打包成可运行的jar包

选择 File-》Project Structure
然后再弹出框中选择 Atifacts -》“+“ -》from modules with dependcents


这里选择main函数运行java类,manifest.mf 文件目录这里 需要将src目录后面的文件夹取掉, 点击ok确认后如下:

以上表示jar包基本配置完成,下来就开始生产jar包。
选择build-》Artifacts


选择jar包-》build即可生成jar包。build是指首次编译,rebuild是首次编译后使用的, 编译后生产jar包如下:

进入到jar包目录

通过cmd命令行运行 java -jar xxx.jar , 如下:

运行后,在弹出框选择需要加密的jar文件、输出加密目录、加密密码。

加密后再d盘生产一个加密文件、xjar.go、xjar_agentable.go .

以上表示加密完成,下面介绍如下运行加密后的文件。

运行加密jar文件

1、安装编译脚本

安装go语言环境下载地址:https://studygolang.com/dl

我这里使用windows开发,下载go1.16.3.windows-amd64.msi , 下载完成直接安装即可。
安装后验证是否安装成功,打开cmd,执行 go env

2、进入到生成加密文件目录,执行编译
go build xjar.go

编译后生产一个xjar.exe文件,后面需要通过该文件运行密码jar包。

通过步骤2加密成功后XJar会在输出的JAR包同目录下生成一个名为 xjar.go 的的Go启动器源码文件.
将 xjar.go 在不同的平台进行编译即可得到不同平台的启动器可执行文件, 其中Windows下文件名为 xjar.exe 而Linux下为 xjar.
用于编译的机器需要安装 Go 环境, 用于运行的机器则可不必安装 Go 环境, 具体安装教程请自行搜索.
由于启动器自带JAR包防篡改校验, 故启动器无法通用, 即便密码相同也不行.

  1. 启动运行

xjar java -jar /path/to/encrypted.jar

xjar javaw -jar /path/to/encrypted.jar

nohup xjar java -jar /path/to/encrypted.jar

centos 安装go

1.下载二进制包

wget https://dl.google.com/go/go1.11.4.linux-amd64.tar.gz

2.将下载的二进制包解压至 /usr/local目录

tar -C /usr/local -xzf go1.4.linux-amd64.tar.gz
3.打开/etc/profile文件

sudo vim /etc/profile
4.将 /usr/local/go/bin 目录添加至PATH环境变量,在/etc/profile文件底部添加如下行

export PATH=$PATH:/usr/local/go/bin
5.应用修改的配置

source /etc/profile
如上则环境配置完成,执行测试看是否安装成功

输入 go version能正常显示版本号,正常安装。

以上表示go安装成功

2、将加密jar包、xjar.go、xjar_agentable.go 上传到服务器。


执行命令: ./xjar java -jar encrypt20210415162050.jar

springboot项目集成xjar 加密工具

源码:https://gitee.com/starsky20/springboot-xjar.git

通过idea创建一个springboot项目,然后引入xjar依赖包

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.7.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>starsky-xjar</artifactId><version>0.0.1-SNAPSHOT</version><name>starsky-xjar</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring.boot.version>2.0.7</spring.boot.version><spring.boot.admin.version>2.0.3</spring.boot.admin.version><spring.cloud.version>Finchley.SR2</spring.cloud.version><spring.cloud.alibaba.version>2.0.3.RELEASE</spring.cloud.alibaba.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- 添加 XJar 依赖 --><dependency><groupId>com.github.core-lib</groupId><artifactId>xjar</artifactId><version>4.0.2</version><!-- <scope>test</scope> --></dependency><dependency><groupId>com.github.core-lib</groupId><artifactId>loadkit</artifactId><version>v1.0.0</version></dependency><dependency><groupId>commons-lang</groupId><artifactId>commons-lang</artifactId><version>2.5</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><fork>true</fork></configuration></plugin><plugin><groupId>com.github.core-lib</groupId><artifactId>xjar-maven-plugin</artifactId><version>4.0.2</version><executions><execution><goals><goal>build</goal></goals><!--可以改成 install--><phase>package</phase><configuration><password>io.xjar</password><!-- 需要加密的资源路径表达式 --><includes><include>com/starsky/**</include><include>mapper/*Mapper.xml</include><include>config/**</include></includes><!-- 无需加密的资源路径表达式 --><excludes><exclude>static/**</exclude><exclude>templates/**</exclude><exclude>resources/**</exclude><exclude>META-INF/resources/**</exclude></excludes><!-- 目标jar存放目录及目标jar名称,也可以用表达式(参考官网) --><targetJar>web-app.jar</targetJar><!-- <targetJar>你的jar包名字</targetJar>--></configuration></execution></executions></plugin></plugins><!-- 资源目录 --><resources><resource><directory>src/main/resources</directory><includes><include>**/*.*</include></includes><!-- 资源根目录排除各环境的配置,防止在生成目录中多余其它目录 --><excludes><exclude>application.properties</exclude><exclude>bootstrap-dev.yml</exclude><exclude>bootstrap-prod.yml</exclude><exclude>bootstrap-test.yml</exclude></excludes><filtering>true</filtering></resource><!--激活指定文件--><resource><directory>src/main/resources</directory><filtering>true</filtering><includes><include>application.properties</include></includes></resource><!--打包java目录--><resource><directory>src/main/java</directory><includes><include>**/*.*</include></includes><excludes><exclude>**/*.java</exclude></excludes><filtering>true</filtering></resource></resources></build><!-- 设置 jitpack.io 仓库 --><repositories><repository><id>jitpack.io</id><url>https://jitpack.io</url></repository></repositories><!-- 设置 jitpack.io 插件仓库 --><pluginRepositories><pluginRepository><id>jitpack.io</id><url>https://jitpack.io</url></pluginRepository></pluginRepositories></project>

注意事项

  1. 不兼容 spring-boot-maven-plugin 的 executable = true 以及 embeddedLaunchScript
<plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><!-- 需要将executable和embeddedLaunchScript参数删除, 目前还不能支持对该模式Jar的加密!后面可能会支持该方式的打包. <configuration><executable>true</executable><embeddedLaunchScript>...</embeddedLaunchScript></configuration>-->
</plugin>

插件集成
Maven项目可通过集成 xjar-maven-plugin 以免去每次加密都要执行一次上述的代码, 随着Maven构建自动生成加密后的JAR和Go启动器源码文件.
xjar-maven-plugin GitHub: https://github.com/core-lib/xjar-maven-plugin

对于Spring Boot 项目或模块, 该插件要后于 spring-boot-maven-plugin 插件执行, 有两种方式:
将插件放置于 spring-boot-maven-plugin 的后面, 因为其插件的默认 phase 也是 package
将插件的 phase 设置为 install(默认值为:package), 打包命令采用 mvn clean install

也可以通过Maven命令执行
mvn xjar:build -Dxjar.password=io.xjar
mvn xjar:build -Dxjar.password=io.xjar -Dxjar.targetDir=/directory/to/save/target.xjar

但通常情况下是让XJar插件绑定到指定的phase中自动执行, 这样就能在项目构建的时候自动构建出加密的包.

mvn clean package -Dxjar.password=io.xjar
mvn clean install -Dxjar.password=io.xjar -Dxjar.targetDir=/directory/to/save/target.xjar

强烈建议
强烈建议不要在 pom.xml 的 xjar-maven-plugin 配置中写上密码,这样会导致打包出来的 xjar 包中的 pom.xml 文件保留着密码,极其容易暴露密码!强烈推荐通过 mvn 命令来指定加密密钥!

打包运行

进入到项目目录,执行命令:
mvn clean package -Dxjar.password=123456789 -Dmaven.test.skip=true
这里打包排除test测试相关代码不打包。


打包完成如下:

进入到打包目录,执行编译 go build xjar.go , 执行后会生成一个xjar.exe文件

通过cmd命令行运行如下:

针对springboot项目加密后,swagger接口 不能通过页面访问,加密后jar包体积大约增加2倍。
至于项目部署是否需要加密处理,根据实际情况进行调整。

实际部署项目为例测试:

1、未加密swagger接口:

未加密jar包,访问swagger接口,可以查看所有接口。

2、加密后,swagger接口访问测试:

可以看到,加密直接访问swagger接口没有任何结果。

3、通过gateway网关测试swagger接口:

通过gateway访问加密服务swagger可以。

通过反编译工具查看加密的jar包

1、正常jar包,通过反编译工具可直接查看,如下:

生成未加密的jar包,通过反编译工具可以直接查看源码,没有任何安全错误,容易被窃取。

2、通过xjar进行加密jar包,如下:

可以看到,我们查看加密后的class文件,直接提示class文件无效,不能直接查看源码了。

springboot xjar 安全加密运行工具相关推荐

  1. tomcat xjar 加密_XJar Spring Boot JAR 安全加密运行工具

    GitHub: https://github.com/core-lib/xjar Spring Boot JAR 安全加密运行工具, 同时支持的原生JAR. 基于对JAR包内资源的加密以及拓展Clas ...

  2. xjar加密后运行错误_XJar: Spring-Boot JAR 包加/解密工具,避免源码泄露以及反编译。...

    XJar Spring Boot JAR 安全加密运行工具,同时支持的原生JAR. 基于对JAR包内资源的加密以及拓展ClassLoader来构建的一套程序加密启动,动态解密运行的方案,避免源码泄露或 ...

  3. xjar 对Spring-Boot JAR 包加密运行工具

    Xjar 介绍 Spring Boot JAR 安全加密运行工具,同时支持的原生JAR. 基于对JAR包内资源的加密以及拓展ClassLoader来构建的一套程序加密启动,动态解密运行的方案,避免源码 ...

  4. JavaScript实现在线MD5、SHA、AES、Rabit 、RC4、TripleDES Ripemd160 加密解密工具-toolfk程序员在线工具网...

    2019独角兽企业重金招聘Python工程师标准>>> 本文要推荐的[ToolFk]是一款程序员经常使用的线上免费测试工具箱,ToolFk 特色是专注于程序员日常的开发工具,不用安装 ...

  5. 【Android 安全】DEX 加密 ( Java 工具开发 | apk 文件签名 )

    文章目录 一.生成 jks 文件 二.签名命令 三.执行结果 四.处理 Unsupported major.minor version 52.0 错误 参考博客 : [Android 安全]DEX 加 ...

  6. 组态王授权产品id和授权锁id_软件加密授权工具推荐

    公司研发一套软件,需要开始往外卖,苦于上市后盗版压力比较大.于是寻找了一款软件加密授权工具-Virbox LM. Virbox LM在加密方面,能快速的完成加密工作,不需要编写代码,安全强度也很高.授 ...

  7. java des加密解密_Java实现的DES加密解密工具类实例

    本文实例讲述了Java实现的DES加密解密工具类.分享给大家供大家参考,具体如下: 一个工具类,很常用,不做深入研究了,那来可直接用 DesUtil.java package lsy; import ...

  8. MD5、SHA、AES、Rabit 、RC4、TripleDES Ripemd160 加密解密工具

    本文要推荐的[ToolFk]是一款程序员经常使用的线上免费测试工具箱,ToolFk 特色是专注于程序员日常的开发工具,不用安装任何软件,只要把内容贴上按一个执行按钮,就能获取到想要的内容结果.Tool ...

  9. JavaScript实现在线MD5、SHA、AES、Rabit 、RC4、TripleDES Ripemd160 加密解密工具-toolfk程序员在线工具网

    本文要推荐的[ToolFk]是一款程序员经常使用的线上免费测试工具箱,ToolFk 特色是专注于程序员日常的开发工具,不用安装任何软件,只要把内容贴上按一个执行按钮,就能获取到想要的内容结果.Tool ...

最新文章

  1. OpenCV中的特征匹配(Feature Matching)
  2. socket编程:I/O模型
  3. node.js(npm)|bower(bootstrap)|git
  4. 处理输入屏幕的互相锁定
  5. android动态改变菜单栏,Android动态设置主题(使用RxBus模式)
  6. c基础学汇编语言,王爽《汇编语言》学习笔记、习题(第一章 基础知识)
  7. HTML知识积累及实践(五) - 表单元素
  8. 开源免费etl作业批量调度必备软件 Taskctl Free应用版
  9. 网易云音乐encseckey算法php,求助网易云音乐_secretKey及_encSecKey获取
  10. SIP电话为什么突然断线
  11. mysql存储视频_特殊格式文件(视频、声音等) 在数据库中的存储方式
  12. 怎么放大整个html页面,怎么把网页的字变大?教你网页操作实用技巧【步骤详解】...
  13. 使用 vscode 编辑html后缀但包含jsp、django、erb、php模板标签时,配置实现正确格式化文档
  14. python打包android的app,出现 Could not load the Qt platform plugin “xcb“的解决方法
  15. matlab 仿真三项异步电机,基于MATLAB三相异步电机的建模与仿真
  16. 以太坊:快速入门 Truffle
  17. 设置Visual Studio颜色主题
  18. C语言系统内存被踩情况总结
  19. 浅谈RAC -- 节点reboot问题的调查方法
  20. 研华工控机主板上电自启

热门文章

  1. 好书推荐:低功耗蓝牙5.x 高级开发
  2. 基于Python的在线办公系统的设计和实现
  3. VHDL学习—双端口存储器
  4. C++构造函数的初始化列表
  5. 神经网络模型每次训练结果不一致
  6. 第7章 缓存雪崩+缓存击穿+缓存穿透
  7. 智能家庭本周锋闻:智能家居缺席Google I/O 大会
  8. 编译原理 —— 正规式、正规集和正则定义
  9. Java快速创建多级目录
  10. 全球招募!GeekPwn2020新增“新基建”安全挑战赛