如何用java语言对即时通讯软件进行加密一、Java软件加密基本思路
对于应用软件的保护笔者从两个方面进行考虑,第一是阻止盗版使用软件,第二是阻止竞争对手对软件反编译 , 即阻止对软件的逆向工程 。
1、阻止盗版
在软件运行时对自身存在的合法性进行判断 , 如果认为自身的存在和运行是被授权的、合法的 , 就运行;否则终止运行 。这样即使软件可以被随意复制,只要盗版用户没有相应的授权信息就无法使用软件 。
2、阻止反编译
对编译产生的Class文件加密处理,并在运行时进行解密,解密者无法对软件进行反编译 。
二、Java软件加密的总体流程
为了保护用Java语言开发的软件,我们设计并实现了一个实用、高强度的加密算法 。以下称需要保护的Java软件为“受保护程序” , 称对“受保护程序”进行加密保护的软件为“加密程序” 。对软件加密保护的流程如图1所示 。
三、加密算法分析设计
1、用户信息提取器设计
为了防止用户发布序列号而导致“一次发行,到处都是”的盗版问题 , 提取用户机器中硬件相关的、具有唯一性的信息——用户计算机的硬盘分区C的序列号 , 并要求用户将此信息与用户名一起返回,之后用“序列号生成器”根据用户返回信息生成一个唯一合法的软件注册序列号发回用户,用户即可使用此号码注册使用软件 。
这个信息提取器使用Winclows 32汇编以一个独立的小程序方式实现,程序代码如图2所示 。
2、序列号生成器与序列号合法性判断函数的设计
序列号生成器与序列号合法性判断函数中运用RSA加密算法 。在序列号生成器中是使用私钥将用户返回的信息(硬盘序列号,用户名)进行加密得到相应的注册序列号;在序列号合法性判断函数中使用私钥将用户输入的注册序列号解密,再与(硬盘序列号,用户名)进行比较,一致则调用程序装载器将程序其他部分解密装入内存 , 初始化删环境并运行程序主体;否则退出 。
RSA加密算法的实现需要使用大数运算库,我们使用MIRACL大数库来实现RSA计算,序列号生成器的主要代码如下:
char szlnputString[]=”机器码和用户名组成的字符串”;
char szSerial[256]=[0];//用于存放生成的注册码
bign,d,c,m; //MIRACL中的大数类型
mip→IBASE=16; //以16进制模式
n= mlrvar(0); //初始化大数
d= mirvar(0);
c= mirvar(0); //C存放输入的字符串大数
m= mlrva(o);
bytes to big( len, szlnputString,c);
//将输入字符串转换成大数形式并存入变量c中
cinstr(n,”以字符串形成表示的模数”);//初始化模数
cinstr(d,”以字符串形成表示的公钥”)://初始化公钥
powmod(c,d,n,m); //计算m=cdmod n
cotstr(m,szSerial);//m的16进制字符串即为注册码
序列号合法性检测函数的主要代码如下:
char szlnputStringL]=”机器码和用户名组成的字符串”;
char szSerial[ 256]=”用户输入的序列号”
bign,e,c,m; //MIRACL中的大数类型
mip→IBASE=16; //以16进制模式
cinstr(m,szSerial); //将序列号的16进制转成大数形式
cinstr(n,”模数n的字符串形式”);//初始化模数n
cinstr(e,”字符串形式的公钥”);//初始化公钥
if compare(m,n)==-1) //mn时才进行解密
{
powmod(m,e,n,c);//计算m=me mod n
big_to _bytes(0,c,szSerial,0); //转为字符串
return lstrcmp( szlnputString,szSerial);
}
3、强耦合关系的设计
如果在序列号合法性检测函数中简单地使用图3所示流程:
解密者可以使用以下几种手段进行攻击:
(1)修改“判断合法性子函数”的返回指令,让它永远返回正确值,这样可以使用任意的序列号,安装/使用软件 。
(2)修改判断后的跳转指令,使程序永远跳到正确的分支运行,效果和上一种一样 。
(3)在“判断合法性子函数”之前执行一条跳转指令,绕过判断,直接跳转到“正常执行”分支运行,这样可以不用输入序列号安装/使用软件 。
为阻止以上攻击手段,笔者在程序中增加了“序列号合法性检测函数”与程序其他部分“强耦合”(即增强其与程序其他部分的关联度,成为程序整体密不可分的一部分,一旦被修改程序将无法正常工作)的要求(见图1),并且设置一个“完整性检测函数”用于判断相关的代码是否被修改过 。当然 , 基于同样的原因 , “完整性检测函数”也必须与程序其他部分存在“强耦合”关系 。
强耦合关系通过以下方式建立:
在程序其他部分的函数(例如函数A)中随机的访问需要强耦合的“序列号合法性检测函数”和“完整性检测函数” , 在调用时随机的选择使用一个错误的序列号或是用户输入的序列号 , 并根据返回结果选择执行A中正常的功能代码还是错误退出的功能代码,流程如图4所示 。
经过这种改进,如果破解者通过修改代码的方式破解将因“完整性检测”失败导致程序退出;如果使用SMC等技术绕过“序列号合法性判断函数”而直接跳至序列号正确时的执行入口,在后续的运行中,将因为随机的耦合调用失败导致程序退出 。破解者要破解软件将不得不跟踪所有进行了耦合调用的函数,这显然是一个艰巨的任务 。
4、完整性检测函数的设计
我们使用CRC算法算出需进行完整性检测的文件的校验码,并用RSA加密算法的公钥(不同于序列号合法性检测中的公钥/私钥对)将其加密存放在特定的文件中,在检测时先用CRC算法重新生成需进行完
整性检测的文件的校验码,并用私钥将保存的校验码解密,两者相比较 , 相等则正常运行;否则退出 。
5、程序加载器的设计
与编译成机器码执行的程序不同,Java程序只能由Java虚拟机解释执行,因此程序加载器的工作包括:初始化Java虚拟机;在内存中解密当前要运行的class文件;使解密后的c:lass文件在虚拟机中运行,在
需要时解密另一个class文件 。图5是用于初始化JVM的代码:
以上介绍了我们设计的针对Java软件的加密保护方法,其中综合运用了多种加密技术,抗破解强度高;使用纯软件保护技术,成本低 。经笔者在Windows系列平台上进行测试,运行稳定,效果良好 。
在研宄开发过程中 , 我们还总结出加密保护软件的一些经验:
1、对关键代码和数据要静态加密,再动态解密执行;要结合具体的工作平台使用反跟踪/调试技术;
2、要充分利用系统的功能,如在Windows下使用DLL文件或驱动程序形式能得到最大的丰又限,可以充分利用系统具有的各种功能;
3、如果可能应该将关键代码存放在不可禚复制的地方;
4、序列号要与机器码等用户信息相关以阻止盐复布序列号;
5、加密流程的合理性比加密算法本身的强度更重要 。
用java写个文件加密的代码该怎么写最简单的就一个FOR循环要加密的文件再声明一个字符串 遍历要加密的文件和字符串进行位与操作或之类操作
类似这样-
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
String str = "hello";
byte[] strCode = str.getBytes();
System.out.println("原始信息字节码:" Arrays.toString(strCode));
String key = "abcde";
byte[] keyCode = key.getBytes();
System.out.println("密钥字节码:" Arrays.toString(keyCode));
byte[] finallyCode = new byte[strCode.length];
for(int i=0;istr.length();i){
finallyCode[i] = (byte) (strCode[i] ^ keyCode[i]);
}
System.out.println("加密后的字节码:" Arrays.toString(finallyCode));
System.out.println("加密后的字符串:" new String(finallyCode));
//============解密
for(int i=0;istr.length();i){
finallyCode[i] = (byte) (finallyCode[i] ^ keyCode[i]);
}
System.out.println("解密后的字节码:" Arrays.toString(finallyCode));
System.out.println("解密后的字符串:" new String(finallyCode));
}
}
分享Java常用几种加密算法简单的Java加密算法有:
第一种. BASE
Base是网络上最常见的用于传输Bit字节代码的编码方式之一 , 大家可以查看RFC~RFC,上面有MIME的详细规范 。Base编码可用于在HTTP环境下传递较长的标识信息 。例如,在Java Persistence系统Hibernate中 , 就采用了Base来将一个较长的唯一标识符(一般为-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数 。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式 。此时,采用Base编码具有不可读性,即所编码的数据不会被人用肉眼所直接看到 。
第二种. MD
MD即Message-Digest Algorithm (信息-摘要算法),用于确保信息传输完整一致 。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD实现 。将数据(如汉字)运算为另一固定长度值 , 是杂凑算法的基础原理,MD的前身有MD、MD和MD 。广泛用于加密和解密技术,常用于文件校验 。校验?不管文件多大,经过MD后都能生成唯一的MD值 。好比现在的ISO校验 , 都是MD校验 。怎么用?当然是把ISO经过MD后产生MD的值 。一般下载linux-ISO的朋友都见过下载链接旁边放着MD的串 。就是用来验证文件是否一致的 。
MD算法具有以下特点:
压缩性:任意长度的数据,算出的MD值长度都是固定的 。
容易计算:从原数据计算出MD值很容易 。
抗修改性:对原数据进行任何改动,哪怕只修改个字节,所得到的MD值都有很大区别 。
弱抗碰撞:已知原数据和其MD值 , 想找到一个具有相同MD值的数据(即伪造数据)是非常困难的 。
强抗碰撞:想找到两个不同的数据,使它们具有相同的MD值,是非常困难的 。
MD的作用是让大容量信息在用数字签名软件签署私人密钥前被”压缩”成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串) 。除了MD以外,其中比较有名的还有sha-、RIPEMD以及Haval等 。
第三种.SHA
安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA) 。对于长度小于^位的消息 , SHA会产生一个位的消息摘要 。该算法经过加密专家多年来的发展和改进已日益完善 , 并被广泛使用 。该算法的思想是接收一段明文 , 然后以一种不可逆的方式将它转换成一段(通常更?。┟芪模?也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输出序列即散列值(也称为信息摘要或信息认证代码)的过程 。散列函数值可以说是对明文的一种“指纹”或是“摘要”所以对散列值的数字签名就可以视为对此明文的数字签名 。
SHA-与MD的比较
因为二者均由MD导出,SHA-和MD彼此很相似 。相应的,他们的强度和其他特性也是相似,但还有以下几点不同:
对强行攻击的安全性:最显著和最重要的区别是SHA-摘要比MD摘要长 位 。使用强行技术,产生任何一个报文使其摘要等于给定报摘要的难度对MD是^数量级的操作,而对SHA-则是^数量级的操作 。这样 , SHA-对强行攻击有更大的强度 。
对密码分析的安全性:由于MD的设计,易受密码分析的攻击,SHA-显得不易受这样的攻击 。
速度:在相同的硬件上 , SHA-的运行速度比MD慢 。
第四种.HMAC
HMAC(Hash Message Authentication Code,散列消息鉴别码,基于密钥的Hash算法的认证协议 。消息鉴别码实现鉴别的原理是,用公开函数和密钥产生一个固定长度的值作为认证标识 , 用这个标识鉴别消息的完整性 。使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输 。接收方利用与发送方共享的密钥进行鉴别认证等 。
谁能提供下java中有关加密和解密的代码public static void main(String[] args) throws Exception {
String data = "https://www.04ip.com/post/itxxz";
System.out.println("字符串:itxxz");
System.err.println("加密:" encrypt(data));
System.err.println("解密:" decrypt(encrypt(data)));
}
运行结果:
由于代码太多 , 可到itxxz.com/a/javashili/2014/1217/encrypt_decrypt.html查看,注释也比较完整,清晰易懂
JAVA简单文件加密 求JAVA源代码md5加密:
package com.ncs.pki.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Test {
private static MessageDigest digest = null;
public synchronized static final String hash(String data) {
if (digest == null) {
try {
digest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException nsae) {
System.err.println(
"Failed to load the MD5 MessageDigest. "
"Jive will be unable to function normally.");
nsae.printStackTrace();
}
}
// Now, compute hash.
digest.update(data.getBytes());
return encodeHex(digest.digest());
}
public static final String encodeHex(byte[] bytes) {
StringBuffer buf = new StringBuffer(bytes.length * 2);
【JAVA中短信加密代码 java密码加密代码】int i;
for (i = 0; ibytes.length; i) {
if (((int) bytes[i]0xff)0x10) {
buf.append("0");
}
buf.append(Long.toString((int) bytes[i]0xff, 16));
}
return buf.toString();
}
public static String test(){
return null;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(MD5Test.hash("123456"));
}
}
3des加密:
package com.ncs.pki.util;
import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class DesEncrypt {
/**
*
* 使用DES加密与解密,可对byte[],String类型进行加密与解密 密文可使用String,byte[]存储.
*
* 方法: void getKey(String strKey)从strKey的字条生成一个Key
*
* String getEncString(String strMing)对strMing进行加密,返回String密文 String
* getDesString(String strMi)对strMin进行解密,返回String明文
*
*byte[] getEncCode(byte[] byteS)byte[]型的加密 byte[] getDesCode(byte[]
* byteD)byte[]型的解密
*/
Key key;
/**
* 根据参数生成KEY
*
* @param strKey
*/
public void getKey(String strKey) {
try {
KeyGenerator _generator = KeyGenerator.getInstance("DES");
_generator.init(new SecureRandom(strKey.getBytes()));
this.key = _generator.generateKey();
_generator = null;
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 加密String明文输入,String密文输出
*
* @param strMing
* @return
*/
public String getEncString(String strMing) {
byte[] byteMi = null;
byte[] byteMing = null;
String strMi = "";
BASE64Encoder base64en = new BASE64Encoder();
try {
byteMing = strMing.getBytes("UTF8");
byteMi = this.getEncCode(byteMing);
strMi = base64en.encode(byteMi);
} catch (Exception e) {
e.printStackTrace();
} finally {
base64en = null;
byteMing = null;
byteMi = null;
}
return strMi;
}
/**
* 解密 以String密文输入,String明文输出
*
* @param strMi
* @return
*/
public String getDesString(String strMi) {
BASE64Decoder base64De = new BASE64Decoder();
byte[] byteMing = null;
byte[] byteMi = null;
String strMing = "";
try {
byteMi = base64De.decodeBuffer(strMi);
byteMing = this.getDesCode(byteMi);
strMing = new String(byteMing, "UTF8");
} catch (Exception e) {
e.printStackTrace();
} finally {
base64De = null;
byteMing = null;
byteMi = null;
}
return strMing;
}
/**
* 加密以byte[]明文输入,byte[]密文输出
*
* @param byteS
* @return
*/
private byte[] getEncCode(byte[] byteS) {
byte[] byteFina = null;
Cipher cipher;
try {
cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, key);
byteFina = cipher.doFinal(byteS);
} catch (Exception e) {
e.printStackTrace();
} finally {
cipher = null;
}
return byteFina;
}
/**
* 解密以byte[]密文输入,以byte[]明文输出
*
* @param byteD
* @return
*/
private byte[] getDesCode(byte[] byteD) {
Cipher cipher;
byte[] byteFina = null;
try {
cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, key);
byteFina = cipher.doFinal(byteD);
} catch (Exception e) {
e.printStackTrace();
} finally {
cipher = null;
}
return byteFina;
}
public static void main(String[] args) {
System.out.println("des demo");
DesEncrypt des = new DesEncrypt();// 实例化一个对像
des.getKey("MYKEY");// 生成密匙
System.out.println("key=MYKEY");
String strEnc = des.getEncString("111111");// 加密字符串,返回String的密文
System.out.println("密文="strEnc);
String strDes = des.getDesString(strEnc);// 把String 类型的密文解密
System.out.println("明文="strDes);
}
}
如何用java程序实现加密的序列号Java是一种跨平台的、解释型语言 。Java 源代码编译中间“字节码”存储于class文件中 。Class文件是一种字节码形式的中间代码,该字节码中包括了很多源代码的信息 , 例如变量名、方法名等 。因此,Java中间代码的反编译就变得非常轻易 。目前市场上有许多免费的、商用的反编译软件,都能够生成高质量的反编译后的源代码 。所以,对开发人员来说,如何保护Java程序就变成了一个非常重要的挑战 。本文首先讨论了保护Java程序的基本方法,然后对代码混淆问题进行深入研究,最后结合一个实际的应用程序 , 分析如何在实践中保护Java程序 。反编译成为保护Java程序的最大挑战通常C、C等编程语言开发的程序都被编译成目标代码 , 这些目标代码都是本机器的二进制可执行代码 。通常所有的源文件被编译、链接成一个可执行文件 。在这些可执行文件中,编译器删除了程序中的变量名称、方法名称等信息,这些信息往往是由内存地址表示,例如假如需要使用一个变量,往往是通过这个变量的地址来访问的 。因此,反编译这些本地的目标代码就是非常困难的 。Java语言的出现,使得反编译变得非常轻易而有效 。原因如下:1.由于跨平台的需求,Java的指令集比较简单而通用,较轻易得出程序的语义信息;2.Java编译器将每一个类编译成一个单独的文件,这也简化了反编译的工作;3.Java 的Class文件中,仍然保留所有的方法名称、变量名称 , 并且通过这些名称来访问变量和方法,这些符号往往带有许多语义信息 。由于Java程序自身的特点,对于不经过处理的Java程序反编译的效果非常好 。目前,市场上有许多Java的反编译工具,有免费的,也有商业使用的 , 还有的是开放源代码的 。这些工具的反编译速度和效果都非常不错 。好的反编译软件,能够反编译出非常接近源代码的程序 。因此 , 通过反编译器 , 黑客能够对这些程序进行更改,或者复用其中的程序 。因此,如何保护Java程序不被反编译,是非常重要的一个问题 。常用的保护技术由于Java字节码的抽象级别较高,因此它们较轻易被反编译 。本节介绍了几种常用的方法,用于保护Java字节码不被反编译 。通常 , 这些方法不能够绝对防止程序被反编译,而是加大反编译的难度而已,因为这些方法都有自己的使用环境和弱点 。隔离Java程序最简单的方法就是让用户不能够访问到Java Class程序 , 这种方法是最根本的方法,具体实现有多种方式 。例如,开发人员可以将要害的Java Class放在服务器端,客户端通过访问服务器的相关接口来获得服务,而不是直接访问Class文件 。这样黑客就没有办法反编译Class文件 。目前,通过接口提供服务的标准和协议也越来越多,例如 HTTP、Web Service、RPC等 。但是有很多应用都不适合这种保护方式,例如对于单机运行的程序就无法隔离Java程序 。这种保护方式见图1所示 。图1隔离Java程序示意图对Class文件进行加密为了防止Class文件被直接反编译,许多开发人员将一些要害的Class文件进行加密 , 例如对注册码、序列号治理相关的类等 。在使用这些被加密的类之前,程序首先需要对这些类进行解密,而后再将这些类装载到JVM当中 。这些类的解密可以由硬件完成,也可以使用软件完成 。在实现时,开发人员往往通过自定义ClassLoader类来完成加密类的装载(注重由于安全性的原因,Applet不能够支持自定义的ClassLoader) 。自定义的ClassLoader首先找到加密的类,而后进行解密,最后将解密后的类装载到JVM当中 。在这种保护方式中 , 自定义的ClassLoader是非常要害的类 。由于它本身不是被加密的,因此它可能成为黑客最先攻击的目标 。假如相关的解密密钥和算法被攻克,那么被加密的类也很轻易被解密 。这种保护方式示意图见图2 。图2 对Class文件进行加密示意图转换成本地代码将程序转换成本地代码也是一种防止反编译的有效方法 。因为本地代码往往难以被反编译 。开发人员可以选择将整个应用程序转换成本地代码,也可以选择要害模块转换 。假如仅仅转换要害部分模块,Java程序在使用这些模块时,需要使用JNI技术进行调用 。当然,在使用这种技术保护Java程序的同时,也牺牲了Java的跨平台特性 。对于不同的平台,我们需要维护不同版本的本地代码 , 这将加重软件支持和维护的工作 。不过对于一些要害的模块 , 有时这种方案往往是必要的 。为了保证这些本地代码不被修改和替代,通常需要对这些代码进行数字签名 。在使用这些本地代码之前,往往需要对这些本地代码进行认证,确保这些代码没有被黑客更改 。假如签名检查通过,则调用相关JNI方法 。这种保护方式示意图见图3 。代码混淆 图3 转换成本地代码示意图代码混淆是对Class文件进行重新组织和处理 , 使得处理后的代码与处理前代码完成相同的功能(语义) 。但是混淆后的代码很难被反编译,即反编译后得出的代码是非常难懂、晦涩的,因此反编译人员很难得出程序的真正语义 。从理论上来说,黑客假如有足够的时间 , 被混淆的代码仍然可能被破解 , 甚至目前有些人正在研制反混淆的工具 。但是从实际情况来看 , 由于混淆技术的多元化发展,混淆理论的成熟,经过混淆的Java代码还是能够很好地防止反编译 。下面我们会具体介绍混淆技术,因为混淆是一种保护Java程序的重要技术 。图4是代码混淆的示意图 。图4 代码混淆示意图几种技术的总结以上几种技术都有不同的应用环境,各自都有自己的弱点,表1是相关特点的比较 。混淆技术介绍表1 不同保护技术比较表 到目前为止,对于Java程序的保护,混淆技术还是最基本的保护方法 。Java混淆工具也非常多,包括商业的、免费的、开放源代码的 。Sun公司也提供了自己的混淆工具 。它们大多都是对Class文件进行混淆处理,也有少量工具首先对源代码进行处理,然后再对Class进行处理 , 这样加大了混淆处理的力度 。目前,商业上比较成功的混淆工具包括JProof公司的1stBarrier系列、Eastridge公司的JShrink和4thpass.com的SourceGuard等 。主要的混淆技术按照混淆目标可以进行如下分类,它们分别为符号混淆(Lexical Obfuscation)、数据混淆(Data Obfuscation)、控制混淆(Control Obfuscation)、预防性混淆(Prevent Transformation) 。符号混淆在Class中存在许多与程序执行本身无关的信息,例如方法名称、变量名称,这些符号的名称往往带有一定的含义 。例如某个方法名为getKeyLength() , 那么这个方法很可能就是用来返回Key的长度 。符号混淆就是将这些信息打乱,把这些信息变成无任何意义的表示 , 例如将所有的变量从vairant_001开始编号;对于所有的方法从method_001开始编号 。这将对反编译带来一定的困难 。对于私有函数、局部变量,通常可以改变它们的符号 , 而不影响程序的运行 。但是对于一些接口名称、公有函数、成员变量,假如有其它外部模块需要引用这些符号,我们往往需要保留这些名称 , 否则外部模块找不到这些名称的方法和变量 。因此,多数的混淆工具对于符号混淆,都提供了丰富的选项,让用户选择是否、如何进行符号混淆 。数据混淆 图5 改变数据访问数据混淆是对程序使用的数据进行混淆 。混淆的方法也有多种,主要可以分为改变数据存储及编码(Store and Encode Transform)、改变数据访问(Access Transform) 。改变数据存储和编码可以打乱程序使用的数据存储方式 。例如将一个有10个成员的数组,拆开为10个变量,并且打乱这些变量的名字;将一个两维数组转化为一个一维数组等 。对于一些复杂的数据结构 , 我们将打乱它的数据结构,例如用多个类代替一个复杂的类等 。另外一种方式是改变数据访问 。例如访问数组的下标时,我们可以进行一定的计算,图5就是一个例子 。在实践混淆处理中 , 这两种方法通常是综合使用的 , 在打乱数据存储的同时,也打乱数据访问的方式 。经过对数据混淆,程序的语义变得复杂了 , 这样增大了反编译的难度 。控制混淆控制混淆就是对程序的控制流进行混淆,使得程序的控制流更加难以反编译,通常控制流的改变需要增加一些额外的计算和控制流,因此在性能上会给程序带来一定的负面影响 。有时,需要在程序的性能和混淆程度之间进行权衡 。控制混淆的技术最为复杂,技巧也最多 。这些技术可以分为如下几类:增加混淆控制 通过增加额外的、复杂的控制流,可以将程序原来的语义隐藏起来 。例如,对于按次序执行的两个语句A、B,我们可以增加一个控制条件,以决定B的执行 。通过这种方式加大反汇编的难度 。但是所有的干扰控制都不应该影响B的执行 。图6就给出三种方式,为这个例子增加混淆控制 。图6 增加混淆控制的三种方式控制流重组 重组控制流也是重要的混淆方法 。例如,程序调用一个方法,在混淆后,可以将该方法代码嵌入到调用程序当中 。反过来,程
关于JAVA中短信加密代码和java密码加密代码的介绍到此就结束了 , 不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站 。
推荐阅读
- hbase自动关闭,hbase设置关闭wal
- 长虹电视屏幕有阴影怎么调,长虹电视屏幕有阴影怎么调节
- go语言定义变量类型 go语言定义数组
- css哪一个可以设置元素背景,css哪一个可以设置元素背景颜色
- 区块链私钥安全方案,区块链公私密钥
- u盘密码忘记了怎么找回密码,u盘忘记密码解锁教程
- go语言tcp连接发包 golang iocopy tcp连接
- jQuery展示PDF,jquery展示一张空白的课表
- 拍摄什么商品好,拍产品用什么摄像机