![]() |
PCDVD數位科技討論區
(https://www.pcdvd.com.tw/index.php)
- 七嘴八舌異言堂
(https://www.pcdvd.com.tw/forumdisplay.php?f=12)
- - 請問 AES加密的實作
(https://www.pcdvd.com.tw/showthread.php?t=1052119)
|
|---|
引用:
我想說在 ecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 這邊才會開始處理raw 看js好像也是在處理前開始作額外的padding動作 所以才想在這邊加入 至於為何不用simpleCrypto http://www.androidsnippets.com/encryptdecrypt-strings 是因為那個java雖有padding的部分 可是加密處理後 出來的長度 與 前輩留下來的js做aes出來的不同 而且其實還有個問題 因為input的資訊 可能只有16byte 結果simpleCrypto http://www.androidsnippets.com/encryptdecrypt-strings 在接收input的部分用的是.getBytes() 結果我的需求是 input ,128 所以這個部分也短少了很多padding的zero 謝謝 |
引用:
真心建議你先"看懂" 並 "消化" 前輩的 js code再來 porting. (聽你的描述你這 js 的 AES code應該有客製過) ,不然沒能綜觀 原始 js code全貌 (公司機密也不可能讓外人看), 這邊就算是神人也難幫得上. PS: 我只是路人甲 打醬油的, 只會嘴砲的廢人一個. |
我對你這語言不熟, 不過以前用 assembly 還有 C 曾經寫過 AES 加解密 library.
其實對於你呼叫者而言, 關於 AES key expansion 甚麼的你都不用去了解內部怎麼跑的, 因為那都是在 AES 演算法方面必定要做的, 你只要照著 call 就行了. 關於你問題的 AES padding (也就是你 input 的 raw), 在呼叫 AES_Encrypt 前就應該要 padding 到以 16 byte 為單位, 因為 AES spec 就是以 16 bytes 為 block size 在加解密的, 你沒有用加解密雙方講好的 padding rule 去 padding 的話, 加解密出來的東西就根本都亂掉了. 還有我看你兩段 code 的 data 還有 private_key 怎麼感覺是相反的. 而且輸入的 data 沒有 length, 那 AES 怎麼知道要處理多少 block ? 還是這函式固定只處理一個 block ? Anyway, 一切還是要靠你自己啊, 感覺問題不難, 你只要花點心思看懂照著 call 就行. |
根據你參考的網頁
raw是Key clear才是Text Padding的部份Java已經有提供幾種模式可以使用! |
引用:
原來如此 了解 那請問一下 在傳入部分 那個method 內部是改接收 bytes[] <-----使用 getbyte()轉換 所以我傳入 16b的資料 也只有 16 b的[] 請問我該如何強制 輸入 128b的[] ? 不滿128的全部在[]補上0 謝謝 |
自己建個128byte的陣列去補滿唄
不過你確定要自己Padding ? 引用:
|
這是包含在修改過的AES 加密的JavaScript的一個步驟
因為原本範例的JavaScript http://point-at-infinity.org/jsaes/jsaes.js 其中要被加密的資料 是 var block = new Array(16); 引用:
而很不湊巧的 這邊我變成是 string輸入 也因此需要在改寫的 JavaScript增加 stringtohex ----> 輸出為 已經轉成hex 的string 然後又用了 這個 hexstr2array 將已經 hex的 block 的string 做 1.額外添加至128 2. 轉成128 做加密運算 PS. 會這樣理解 是因為JavaScript裡面是這樣用法 代碼:
var plaintext_byte = hexstr2array(plaintext_hex, 128); 然後 原始的AES範例的JavaScript 在加密前另外是這樣處理 代碼:
* var block = new Array(16); * for(var i = 0; i < 16; i++) * block[i] = 0x11 * i; 而修改過的AES JavaScript則是 代碼:
var block = new Array(32);
for (var j=0; j<32; j++)
{
block[j] = passwd_byte[i*32+j];
}
block = AES_Encrypt(block,plaintext_byte);
現在整個被JS無形別的var搞得很混亂 謝謝 |
我聽說
用Java 寫的obj code 如果被取得,很容易反組譯回來 , 不知是否為真 ?? 我最近也是有花了一部份的時間,想實作透過HTTPS來傳送key string 給client , 來做為 client端解開軟體使用的動作!! 不敢用Java來寫,就是怕有心人會破解obj code 來取得演算法 ,演算法一旦被取得,就等於軟體被破解.... :stupefy: :stupefy: :stupefy: 想來想去,還是乖乖的回到C語言來寫程式.... :think: 另外為了防破解,還得想一些干擾程式來運作..... :nonono: |
如果沒有經過混淆,Java/.Net的中介檔要反編譯回去毫無困難
你真的那麼擔心的話 只有把關鍵演算法放在你自己的伺服器上才能避免 引用:
|
改了java檔先測試
因為網路那個SimpleCrypto要的是 byte [] 所以我把hexstr2array改成byte[]輸出 可是目前都會 NullPointerException 請幫我看看哪邊改錯了 謝謝 代碼:
import java.security.SecureRandom;
import java.util.logging.Logger;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class aestest {
public static void main(String args[]) throws Exception
{
String a = "1234567890ABCDEF";
String privateK = "qqqqqqqqqqqqq";
// System.out.print( a.getBytes());
// System.out.println();
// System.out.print( privateK.getBytes());
// System.out.println();
//
// System.out.print( "toHexString : "+toHex(a));
// System.out.println();
// System.out.print( "toHexString : " +toHex(privateK));
// System.out.println();
//
// System.out.print( "toHexString and then fromHex : "+fromHex(toHex(a)));
// System.out.println();
// System.out.print( "toHexString and then fromHex : " +fromHex(toHex(privateK)));
// System.out.println();
// System.out.printf( encrypt(privateK,a));
System.out.printf( encrypt(a,privateK));
System.out.println();
// int b[] = hexstr2array(a, 4);
//
// for(int c: b)
// System.out.printf("%d ", c);
// System.out.println();
}
// public static int[] hexstr2array(String input, int length)
// {
// int[] output = new int[length];
//
// for(int i = 0; i < length; i++)
// if(i < input.length() / 2)
// output[i] = Integer.parseInt(input.substring(i*4, i*4+4), 16);
// else
// output[i] = 0;
//
// return output;
// }
public static String encrypt(String seed, String cleartext) throws Exception {
System.out.print( "input : "+seed);
System.out.println();
System.out.print( "input length : "+ seed.length());
System.out.println();
System.out.print( seed.getBytes());
System.out.println();
System.out.print( "input to Bytes length : "+seed.getBytes().length);
System.out.println();
// System.out.print(byteArray2int( seed.getBytes()));
// System.out.println();
// System.out.print( "seed.getBytes().toString() user 16 hexstr2array "+hexstr2array(seed.getBytes().toString(),16));
// System.out.println();
System.out.print( "input to Hex : "+toHex(seed));
System.out.println();
System.out.print( "input to Hex length : "+toHex(seed).length());
System.out.println();
// System.out.print( "input to Hex to 16 hexstr2array : "+hexstr2array(toHex(seed),16));
// System.out.println();
//
// System.out.print( "input to Hex to 32 hexstr2array : "+hexstr2array(toHex(seed),32));
// System.out.println();
System.out.print( "input to Hex to 64 hexstr2array : "+hexstr2array(toHex(seed),64));
System.out.println();
System.out.print( "input to Hex to 64 hexstr2arrayi : "+hexstr2arrayi(toHex(seed),64));
System.out.println();
System.out.print( "input to Hex to byte to 32 hexstr2arrayb : "+hexstr2arrayb(seed,64));
System.out.println();
// System.out.print( "user 8 hexstr2array "+hexstr2array(seed,8));
// System.out.println();
//
//
System.out.print( "user 16 hexstr2array "+hexstr2array(seed,16));
System.out.println();
//
// System.out.print( "user 32 hexstr2array "+hexstr2array(seed,32));
// System.out.println();
//
// System.out.print( "user 64 hexstr2array "+hexstr2array(seed,64));
// System.out.println();
//
// System.out.print( "user 128 hexstr2array "+hexstr2array(seed,128));
// System.out.println();
// System.out.print(byteArray2int( seed.getBytes()));
// System.out.println();
byte[] rawKey = getRawKey(seed.getBytes());
byte[] result = encrypt(rawKey, cleartext.getBytes());
return toHex(result);
}
//public static String decrypt(String seed, String encrypted) throws Exception {
// byte[] rawKey = getRawKey(seed.getBytes());
// byte[] enc = toByte(encrypted);
// byte[] result = decrypt(rawKey, enc);
// return new String(result);
//}
private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
//private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
// SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
// Cipher cipher = Cipher.getInstance("AES");
// cipher.init(Cipher.DECRYPT_MODE, skeySpec);
// byte[] decrypted = cipher.doFinal(encrypted);
// return decrypted;
//}
public static String toHex(String txt) {
///////This let input String to HEX
int i=0;
// System.out.print("run No.= "+i+ " Show input : "+txt);
// i++;
return toHex(txt.getBytes());
}
//public static String fromHex(String hex) {
// ///////This let HEX to String
// int i=0;
// System.out.print("run No.= "+i+ " Show input : "+hex);
// i++;
// return new String(toByte(hex));
//}
//public static byte[] toByte(String hexString) {
// int len = hexString.length()/2;
// byte[] result = new byte[len];
// for (int i = 0; i < len; i++)
// result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
// return result;
//}
public static String toHex(byte[] buf) {
if (buf == null)
return "";
StringBuffer result = new StringBuffer(2*buf.length);
for (int i = 0; i < buf.length; i++) {
appendHex(result, buf[i]);
}
return result.toString();
}
public static byte[] int2byteArray(int num) {
////int to byte
byte[] result = new byte[4];
result[0] = (byte)(num >>> 24);//取最高8位放到0下標
result[1] = (byte)(num >>> 16);//取次高8为放到1下標
result[2] = (byte)(num >>> 8); //取次低8位放到2下標
result[3] = (byte)(num ); //取最低8位放到3下標
return result;
}
//public static byte int2byte(int num) {
// ////int to byte
// byte result = new byte;
// result[0] = (byte)(num >>> 24);//取最高8位放到0下標
// result[1] = (byte)(num >>> 16);//取次高8为放到1下標
// result[2] = (byte)(num >>> 8); //取次低8位放到2下標
// result[3] = (byte)(num ); //取最低8位放到3下標
// return result;
//}
public static int byteArray2int(byte[] b){
////// byte to int
byte[] a = new byte[4];
int i = a.length - 1,j = b.length - 1;
for (; i >= 0 ; i--,j--) {//從b的尾部(即int值的低位)開始copy數據
if(j >= 0)
a[i] = b[j];
else
a[i] = 0;//如果b.length不足4,則將高位補0
}
int v0 = (a[0] & 0xff) << 24;//&0xff將byte值無差異轉成int,避免Java自動類型提升後,會保留高位的符號位
int v1 = (a[1] & 0xff) << 16;
int v2 = (a[2] & 0xff) << 8;
int v3 = (a[3] & 0xff) ;
return v0 + v1 + v2 + v3;
}
public static String[] hexstr2array(String input,int length) {
String[] output = new String[length];
for (int i=0; i<length; i++) {
if (i < (input.length())/2) {
int ss = Integer.parseInt(input.substring((i*2),(i*2+2)),16);
output[i] =""+ss;
} else {
output[i] = "0";
}
}
return output;
}
public static int[] hexstr2arrayi(String input,int length) {
int[] output = new int[length];
for (int i=0; i<length; i++) {
if (i < (input.length())/2) {
int ss = Integer.parseInt(input.substring((i*2),(i*2+2)),16);
output[i] = ss;
} else {
output[i] = 0 ;
}
}
return output;
}
public static byte[] hexstr2arrayb(String input,int length) {
byte[] output = new byte[length];
for (int i=0; i<length; i++) {
if (i < (input.length())/2) {
//int ss = Integer.parseInt(input.substring((i*2),(i*2+2)),16);
//output[i] = ss;
//output[i] = int2byteArray(ss);
for (int j= 0; j < length; j += 2) {
byte[] data = null;
data[j / 2] = (byte) ((Character.digit(input.charAt(j), 16) << 4)
+ Character.digit(input.charAt(j+1), 16));
}
} else {
output[i] = 0 ;
}
}
return output;
}
private final static String HEX = "0123456789ABCDEF";
private static void appendHex(StringBuffer sb, byte b) {
sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
}
}
|
| 所有的時間均為GMT +8。 現在的時間是01:58 PM. |
vBulletin Version 3.0.1
powered_by_vbulletin 2026。