A. 【轉】如何保護java代碼
以下從技術角度就常見的保護措施 和常用工具來看看如何有效保護java代碼:1. 將java包裝成exe 特點:將jar包裝成可執行文件,便於使用,但對java程序沒有任何保護。不要以為生成了exe就和普通可執行文件效果一樣了。這些包裝成exe的程序運行時都會將jar文件釋放到臨時目錄,很容易獲取。常用的工具有exe4j、jsmooth、NativeJ等等。jsmooth生成的exe運行時臨時目錄在exe所在目錄中或是用戶臨時目錄 中;exe4j生成的exe運行時臨時目錄在用戶臨時目錄中;NativeJ生成的exe直接用winrar打開,然後用zip格式修復成一個jar文件,就得到了原文件。如果只是為了使用和發布方便,不需要保護java代碼,使用這些工具是很好的選擇。2. java混淆器特點:使用一種或多種處理方式將class文件、java源代碼進行混淆處理後生成新的class,使混淆後的代碼不易被反編譯,而反編譯後的代碼難以閱 讀和理解。這類混淆器工具很多,而且也很有成效。缺點:雖然混淆的代碼反編譯後不易讀懂,但對於有經驗的人或是多花些時間,還是能找到或計算出你代碼中隱藏的敏感內容,而且在很多應用中不是全部代碼都能混淆的,往往一些關鍵的庫、類名、方法名、變數名等因使用要求的限制反而還不能混淆。3. 隔離java程序到服務端特點:把java程序放到服務端,讓用戶不能訪問到class文件和相關配套文件,客戶端只通過介面訪問。這種方式在客戶/服務模式的應用中能較好地保護java代碼。缺點是:必須是客戶/服務模式,這種特點限制了此種方式的使用范圍;客戶端因為邏輯的暴露始終是較為薄弱的環節,所以訪問介面時一般都需要安全性認證。4. java加密保護特點:自定義ClassLoader,將class文件和相關文件加密,運行時由此ClassLoader解密相關文件並裝載類,要起到保護作用必須自定 義本地代碼執行器將自定義ClassLoader和加密解密的相關類和配套文件也保護起來。此種方式能很有效地保護java代碼。缺點:可以通過替換JRE包中與類裝載相關的java類或虛擬機動態庫截獲java位元組碼。 jar2exe屬於這類工具。5. 提前編譯技術(AOT) 特點:將java代碼靜態編譯成本地機器碼,脫離通用JRE。此種方式能夠非常有效地保護java代碼,且程序啟動比通用JVM快一點。具有代表性的是GNU的gcj,可以做到對java代碼完全提前編譯,但gcj存在諸多局限性,如:對JRE 5不能完整支持、不支持JRE 6及以後的版本。由於java平台的復雜性,做到能及時支持最新java版本和JRE的完全提前編譯是非常困難的,所以這類工具往往採取靈活方式,該用即時編譯的地方還是 要用,成為提前編譯和即時編譯的混合體。缺點:由於與通用JRE的差異和java運用中的復雜性,並非java程序中的所有jar都能得到完全的保護;只能使用此種工具提供的一個運行環境,如果工具更新滯後或你需要特定版本的JRE,有可能得不到此種工具的支持。 Excelsior JET屬於這類工具。6. 使用jni方式保護特點:將敏感的方法和數據通過jni方式處理。此種方式和「隔離java程序到服務端」有些類似,可以看作把需要保護的代碼和數據「隔離」到動態庫中,不同的是可以在單機程序中運用。缺點和上述「隔離java程序到服務端」類似。7. 不脫離JRE的綜合方式保護特點:非提前編譯,不脫離JRE,採用多種軟保護方式,從多方面防止java程序被竊取。此種方式由於採取了多種保護措施,比如自定義執行器和裝載器、加密、JNI、安全性檢測、生成可執行文件等等,使保護力度大大增強,同樣能夠非常有效地保護java代碼。缺點:由於jar文件存在方式的改變和java運用中的復雜性,並非java程序中的所有jar都能得到完全的保護;很有可能並不支持所有的JRE版本。 JXMaker屬於此類工具。8. 用加密鎖硬體保護特點:使用與硬體相關的專用程序將java虛擬機啟動程序加殼,將虛擬機配套文件和java程序加密,啟動的是加殼程序,由加殼程序建立一個與硬體相關的 受保護的運行環境,為了加強安全性可以和加密鎖內植入的程序互動。此種方式與以上「不脫離JRE的綜合方式保護」相似,只是使用了專用硬體設備,也能很好地保護java代碼。缺點:有人認為加密鎖用戶使用上不太方便,且每個安裝需要附帶一個。從以上描述中我們可以看出:1. 各種保護方式都有其優缺點,應根據實際選用2. 要更好地保護java代碼應該使用綜合的保護措施3. 單機環境中要真正有效保護java代碼,必須要有本地代碼程序配合當然,安全都是相對的,一方面看你的保護措施和使用的工具能達到的程度,一方面看黑客的意願和能力,不能只從技術上保護知識產權。總之,在java 代碼保護方面可以採取各種可能的方式,不可拘泥於那些條條框框。
B. 怎麼對加密的JAVA class文件進行解密
JAVA class文件加密解密
package com..encrypt;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
public class FileEncryptAndDecrypt {
/**
* 文件file進行加密
* @param fileUrl 文件路徑
* @param key 密碼
* @throws Exception
*/
public static void encrypt(String fileUrl, String key) throws Exception {
File file = new File(fileUrl);
String path = file.getPath();
if(!file.exists()){
return;
}
int index = path.lastIndexOf("\\");
String destFile = path.substring(0, index)+"\\"+"abc";
File dest = new File(destFile);
InputStream in = new FileInputStream(fileUrl);
OutputStream out = new FileOutputStream(destFile);
byte[] buffer = new byte[1024];
int r;
byte[] buffer2=new byte[1024];
while (( r= in.read(buffer)) > 0) {
for(int i=0;i<r;i++)
{
byte b=buffer[i];
buffer2[i]=b==255?0:++b;
}
out.write(buffer2, 0, r);
out.flush();
}
in.close();
out.close();
file.delete();
dest.renameTo(new File(fileUrl));
appendMethodA(fileUrl, key);
System.out.println("加密成功");
}
/**
*
* @param fileName
* @param content 密鑰
*/
public static void appendMethodA(String fileName, String content) {
try {
// 打開一個隨機訪問文件流,按讀寫方式
RandomAccessFile randomFile = new RandomAccessFile(fileName, "rw");
// 文件長度,位元組數
long fileLength = randomFile.length();
//將寫文件指針移到文件尾。
randomFile.seek(fileLength);
randomFile.writeBytes(content);
randomFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 解密
* @param fileUrl 源文件
* @param tempUrl 臨時文件
* @param ketLength 密碼長度
* @return
* @throws Exception
*/
public static String decrypt(String fileUrl, String tempUrl, int keyLength) throws Exception{
File file = new File(fileUrl);
if (!file.exists()) {
return null;
}
File dest = new File(tempUrl);
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
InputStream is = new FileInputStream(fileUrl);
OutputStream out = new FileOutputStream(tempUrl);
byte[] buffer = new byte[1024];
byte[] buffer2=new byte[1024];
byte bMax=(byte)255;
long size = file.length() - keyLength;
int mod = (int) (size%1024);
int div = (int) (size>>10);
int count = mod==0?div:(div+1);
int k = 1, r;
while ((k <= count && ( r = is.read(buffer)) > 0)) {
if(mod != 0 && k==count) {
r = mod;
}
for(int i = 0;i < r;i++)
{
byte b=buffer[i];
buffer2[i]=b==0?bMax:--b;
}
out.write(buffer2, 0, r);
k++;
}
out.close();
is.close();
return tempUrl;
}
/**
* 判斷文件是否加密
* @param fileName
* @return
*/
public static String readFileLastByte(String fileName, int keyLength) {
File file = new File(fileName);
if(!file.exists())return null;
StringBuffer str = new StringBuffer();
try {
// 打開一個隨機訪問文件流,按讀寫方式
RandomAccessFile randomFile = new RandomAccessFile(fileName, "r");
// 文件長度,位元組數
long fileLength = randomFile.length();
//將寫文件指針移到文件尾。
for(int i = keyLength ; i>=1 ; i--){
randomFile.seek(fileLength-i);
str.append((char)randomFile.read());
}
randomFile.close();
return str.toString();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
C. 如何用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 增加混淆控制的三種方式控制流重組 重組控制流也是重要的混淆方法。例如,程序調用一個方法,在混淆後,可以將該方法代碼嵌入到調用程序當中。反過來,程
D. javaclass類加密後 如何部署到tomcat
1.使用加密程序對classes下所有文件加密,加密之後所有的class文件後綴變為uikoo9,可以自己修改源代碼
2.將原classes文件夾刪除,將加密後的classes文件夾復制進去
3.修改context.xml
4.tomcat\lib下添加loader.class
5.啟動tomcat!
E. 如何對java的class類進行加密
可以使用Virbox Protector Standalone 加殼工具對java的class類進行加密,支持各種開發語言的程序加密。可防止代碼反編譯,更安全,更方便
產品簡介
Virbox Protector Standalone提供了強大的代碼虛擬化、高級混淆與智能壓縮技術,保護您的程序免受逆向工程和非法修改。
Virbox Protector Standalone 將被保護的程序代碼轉換為虛擬機代碼,程序運行時,虛擬機將模擬程序執行,進入和離開虛擬機都有高級代碼混淆。虛擬機配合代碼混淆可以達到很好的保護效果,尤其是開發者的私有邏輯。高級混淆利用花指令和代碼非等價變形等技術,將程序的代碼,轉換成一種功能上等價,但是難於閱讀和理解的代碼,可充分干擾靜態分析。應用程序的解壓縮含有動態密碼,讓一切自動脫殼工具失效,有效的阻止.Net、PE 程序的直接反編譯。
特點
多種加密策略:代碼虛擬化、高級混淆、智能壓縮
性能分析:智能分析引擎,一鍵分析各個函數模塊調用的次數
支持多種開發語言:多種開發語言加殼支持
源碼級保護:保護到匯編級別,c#保護IL級別
免費更新:免費版本升級
F. 如何用JAVA實現字元串簡單加密解密
java加密字元串可以使用des加密演算法,實例如下:
package test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.*;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
/**
* 加密解密
*
* @author shy.qiu
* @since
*/
public class CryptTest {
/**
* 進行MD5加密
*
* @param info
* 要加密的信息
* @return String 加密後的字元串
*/
public String encryptToMD5(String info) {
byte[] digesta = null;
try {
// 得到一個md5的消息摘要
MessageDigest alga = MessageDigest.getInstance("MD5");
// 添加要進行計算摘要的信息
alga.update(info.getBytes());
// 得到該摘要
digesta = alga.digest();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
// 將摘要轉為字元串
String rs = byte2hex(digesta);
return rs;
}
/**
* 進行SHA加密
*
* @param info
* 要加密的信息
* @return String 加密後的字元串
*/
public String encryptToSHA(String info) {
byte[] digesta = null;
try {
// 得到一個SHA-1的消息摘要
MessageDigest alga = MessageDigest.getInstance("SHA-1");
// 添加要進行計算摘要的信息
alga.update(info.getBytes());
// 得到該摘要
digesta = alga.digest();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
// 將摘要轉為字元串
String rs = byte2hex(digesta);
return rs;
}
// //////////////////////////////////////////////////////////////////////////
/**
* 創建密匙
*
* @param algorithm
* 加密演算法,可用 DES,DESede,Blowfish
* @return SecretKey 秘密(對稱)密鑰
*/
public SecretKey createSecretKey(String algorithm) {
// 聲明KeyGenerator對象
KeyGenerator keygen;
// 聲明 密鑰對象
SecretKey deskey = null;
try {
// 返回生成指定演算法的秘密密鑰的 KeyGenerator 對象
keygen = KeyGenerator.getInstance(algorithm);
// 生成一個密鑰
deskey = keygen.generateKey();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
// 返回密匙
return deskey;
}
/**
* 根據密匙進行DES加密
*
* @param key
* 密匙
* @param info
* 要加密的信息
* @return String 加密後的信息
*/
public String encryptToDES(SecretKey key, String info) {
// 定義 加密演算法,可用 DES,DESede,Blowfish
String Algorithm = "DES";
// 加密隨機數生成器 (RNG),(可以不寫)
SecureRandom sr = new SecureRandom();
// 定義要生成的密文
byte[] cipherByte = null;
try {
// 得到加密/解密器
Cipher c1 = Cipher.getInstance(Algorithm);
// 用指定的密鑰和模式初始化Cipher對象
// 參數:(ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE,UNWRAP_MODE)
c1.init(Cipher.ENCRYPT_MODE, key, sr);
// 對要加密的內容進行編碼處理,
cipherByte = c1.doFinal(info.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
// 返回密文的十六進制形式
return byte2hex(cipherByte);
}
/**
* 根據密匙進行DES解密
*
* @param key
* 密匙
* @param sInfo
* 要解密的密文
* @return String 返回解密後信息
*/
public String decryptByDES(SecretKey key, String sInfo) {
// 定義 加密演算法,
String Algorithm = "DES";
// 加密隨機數生成器 (RNG)
SecureRandom sr = new SecureRandom();
byte[] cipherByte = null;
try {
// 得到加密/解密器
Cipher c1 = Cipher.getInstance(Algorithm);
// 用指定的密鑰和模式初始化Cipher對象
c1.init(Cipher.DECRYPT_MODE, key, sr);
// 對要解密的內容進行編碼處理
cipherByte = c1.doFinal(hex2byte(sInfo));
} catch (Exception e) {
e.printStackTrace();
}
// return byte2hex(cipherByte);
return new String(cipherByte);
}
// /////////////////////////////////////////////////////////////////////////////
/**
* 創建密匙組,並將公匙,私匙放入到指定文件中
*
* 默認放入mykeys.bat文件中
*/
public void createPairKey() {
try {
// 根據特定的演算法一個密鑰對生成器
KeyPairGenerator keygen = KeyPairGenerator.getInstance("DSA");
// 加密隨機數生成器 (RNG)
SecureRandom random = new SecureRandom();
// 重新設置此隨機對象的種子
random.setSeed(1000);
// 使用給定的隨機源(和默認的參數集合)初始化確定密鑰大小的密鑰對生成器
keygen.initialize(512, random);// keygen.initialize(512);
// 生成密鑰組
KeyPair keys = keygen.generateKeyPair();
// 得到公匙
PublicKey pubkey = keys.getPublic();
// 得到私匙
PrivateKey prikey = keys.getPrivate();
// 將公匙私匙寫入到文件當中
doObjToFile("mykeys.bat", new Object[] { prikey, pubkey });
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
/**
* 利用私匙對信息進行簽名 把簽名後的信息放入到指定的文件中
*
* @param info
* 要簽名的信息
* @param signfile
* 存入的文件
*/
public void signToInfo(String info, String signfile) {
// 從文件當中讀取私匙
PrivateKey myprikey = (PrivateKey) getObjFromFile("mykeys.bat", 1);
// 從文件中讀取公匙
PublicKey mypubkey = (PublicKey) getObjFromFile("mykeys.bat", 2);
try {
// Signature 對象可用來生成和驗證數字簽名
Signature signet = Signature.getInstance("DSA");
// 初始化簽署簽名的私鑰
signet.initSign(myprikey);
// 更新要由位元組簽名或驗證的數據
signet.update(info.getBytes());
// 簽署或驗證所有更新位元組的簽名,返回簽名
byte[] signed = signet.sign();
// 將數字簽名,公匙,信息放入文件中
doObjToFile(signfile, new Object[] { signed, mypubkey, info });
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 讀取數字簽名文件 根據公匙,簽名,信息驗證信息的合法性
*
* @return true 驗證成功 false 驗證失敗
*/
public boolean validateSign(String signfile) {
// 讀取公匙
PublicKey mypubkey = (PublicKey) getObjFromFile(signfile, 2);
// 讀取簽名
byte[] signed = (byte[]) getObjFromFile(signfile, 1);
// 讀取信息
String info = (String) getObjFromFile(signfile, 3);
try {
// 初始一個Signature對象,並用公鑰和簽名進行驗證
Signature signetcheck = Signature.getInstance("DSA");
// 初始化驗證簽名的公鑰
signetcheck.initVerify(mypubkey);
// 使用指定的 byte 數組更新要簽名或驗證的數據
signetcheck.update(info.getBytes());
System.out.println(info);
// 驗證傳入的簽名
return signetcheck.verify(signed);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 將二進制轉化為16進制字元串
*
* @param b
* 二進制位元組數組
* @return String
*/
public String byte2hex(byte[] b) {
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
if (stmp.length() == 1) {
hs = hs + "0" + stmp;
} else {
hs = hs + stmp;
}
}
return hs.toUpperCase();
}
/**
* 十六進制字元串轉化為2進制
*
* @param hex
* @return
*/
public byte[] hex2byte(String hex) {
byte[] ret = new byte[8];
byte[] tmp = hex.getBytes();
for (int i = 0; i < 8; i++) {
ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
}
return ret;
}
/**
* 將兩個ASCII字元合成一個位元組; 如:"EF"--> 0xEF
*
* @param src0
* byte
* @param src1
* byte
* @return byte
*/
public static byte uniteBytes(byte src0, byte src1) {
byte _b0 = Byte.decode("0x" + new String(new byte[] { src0 }))
.byteValue();
_b0 = (byte) (_b0 << 4);
byte _b1 = Byte.decode("0x" + new String(new byte[] { src1 }))
.byteValue();
byte ret = (byte) (_b0 ^ _b1);
return ret;
}
/**
* 將指定的對象寫入指定的文件
*
* @param file
* 指定寫入的文件
* @param objs
* 要寫入的對象
*/
public void doObjToFile(String file, Object[] objs) {
ObjectOutputStream oos = null;
try {
FileOutputStream fos = new FileOutputStream(file);
oos = new ObjectOutputStream(fos);
for (int i = 0; i < objs.length; i++) {
oos.writeObject(objs[i]);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 返回在文件中指定位置的對象
*
* @param file
* 指定的文件
* @param i
* 從1開始
* @return
*/
public Object getObjFromFile(String file, int i) {
ObjectInputStream ois = null;
Object obj = null;
try {
FileInputStream fis = new FileInputStream(file);
ois = new ObjectInputStream(fis);
for (int j = 0; j < i; j++) {
obj = ois.readObject();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return obj;
}
/**
* 測試
*
* @param args
*/
public static void main(String[] args) {
CryptTest jiami = new CryptTest();
// 執行MD5加密"Hello world!"
System.out.println("Hello經過MD5:" + jiami.encryptToMD5("Hello"));
// 生成一個DES演算法的密匙
SecretKey key = jiami.createSecretKey("DES");
// 用密匙加密信息"Hello world!"
String str1 = jiami.encryptToDES(key, "Hello");
System.out.println("使用des加密信息Hello為:" + str1);
// 使用這個密匙解密
String str2 = jiami.decryptByDES(key, str1);
System.out.println("解密後為:" + str2);
// 創建公匙和私匙
jiami.createPairKey();
// 對Hello world!使用私匙進行簽名
jiami.signToInfo("Hello", "mysign.bat");
// 利用公匙對簽名進行驗證。
if (jiami.validateSign("mysign.bat")) {
System.out.println("Success!");
} else {
System.out.println("Fail!");
}
}
}
G. 我手頭有一個web系統,很多java class類都是加密的,是用classloader.dll載入
樓主你好,這種錯誤不在現場調試,沒有人可以給出一個正確的答案,而且還是偶爾報錯,屬於「幽靈事件」,我大致給出一個思路,jvm中類的載入器都遵循雙親委派模型,如果不清楚,網上可以了解下,而tomcat是正統的類載入器架構,如圖:
其中WebAppClassLoader會去載入/Webapp/WEB-INF/*中的Java類庫,所以,上述報錯可能與java環境出錯有關,可能java jar包殘缺,
並且報錯也隱約看出來,我認為是java 環境的問題,樓主看參考解決下,望對你有所幫助!
H. JAVA程序加密,怎麼做才安全
程序加密?你說的是代碼加密還是數據加密。我都說一下吧。
Java代碼加密:
這點因為Java是開源的,想達到完全加密,基本是不可能的,因為在反編譯的時候,雖然反編譯回來的時候可能不是您原來的代碼,但是意思是接近的,所以是不行的。
那麼怎麼增加反編譯的難度(閱讀難度),那麼可以採用多層繼承(實現)方式來解決,這樣即使反編譯出來的代碼,可讀性太差,復用性太差了。
Java數據加密:
我們一般用校驗性加密,常用的是MD5,優點是速度快,數據佔用空間小。缺點是不可逆,所以我們一般用來校驗數據有沒有被改動等。
需要可逆,可以選用base64,Unicode,缺點是沒有密鑰,安全性不高。
而我們需要可逆而且採用安全的方式是:對稱加密和非堆成加密,我們常用的有AES、DES等單密鑰和雙密鑰的方式。而且是各種語言通用的。
全部手動敲字,望採納,下面是我用Javascript方式做的一系列在線加密/解密工具:
http://www.sojson.com/encrypt.html
I. 用JAVA設計一個簡單的加密、解密演算法,用該演算法來實現對數據的加密、解密
簡單的?
用異或就可以了..!
importjava.util.Scanner;
publicclass加密
{
privatestaticScannersc=newScanner(System.in);
publicstaticvoidmain(String[]Args)
{
System.out.println(" ================字元串加密演示===================== ");
init();
}
//初始化!
privatestaticvoidinit()
{
for(;;)
{
char[]arr=input();
jiaMi(arr,20140908);
jiaMi(20140908,arr);
}
}
//鍵盤錄取!
privatestaticchar[]input()
{
Strings=sc.nextLine();
inta=s.length();
char[]arr=newchar[a];
//char[]arr=s.toCharArray();
for(inti=0;i<s.length();i++)
{
arr[i]=s.charAt(i);
}
returnarr;
}
//加密!!
privatestaticvoidjiaMi(char[]arr,inta)
{
for(inti=0;i<arr.length;i++)
{
arr[i]=((char)(arr[i]^a));
}
System.out.println("加密完成!");
print(arr);
}
//解密!!
privatestaticvoidjiaMi(inta,char[]arr)
{
for(inti=0;i<arr.length;i++)
{
arr[i]=((char)(arr[i]^a));
}
System.out.println("解密完成");
print(arr);
}
//列印!!
privatestaticvoidprint(char[]arr)
{
for(inti=0;i<arr.length;i++)
{
System.out.print(arr[i]);
}
System.out.println(" ========================= ");
}
}