日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java mac pos_pos终端mac国密(sm4)算法(java实现)

發布時間:2025/3/15 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java mac pos_pos终端mac国密(sm4)算法(java实现) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概念理解

mac算法是(Message Authentication Codes 消息認證碼算法),是含有密鑰散列函數算法。主要通過異或運算,再配合其他加密算法實現mac值的運算,用于校驗。

實現過程

將需要加密計算的字符串轉換為16進制字符串

例如:

密鑰:"12345678901234567890123456789012"

待加密數據(字符串形式):

6000112018111411003020170930101010120171025000755000000005553

轉化為16進制:

36303030 31313230 31383131 31343131 30303330 32303137 30393330 31303130 31303132 30313731 30323530 30303735 35303030 30303030 30353535 33

將轉換過的16字符串進行補位分組

部位后的數據(部位規則:字符長度%32!=0補位)

36303030 31313230 31383131 31343131 30303330 32303137 30393330 31303130 31303132 30313731 30323530 30303735 35303030 30303030 30353535 33000000

分組后的數據

第 0組明文:36303030 31313230 31383131 31343131

第 1組明文:30303330 32303137 30393330 31303130

第 2組明文:31303132 30313731 30323530 30303735

第 3組明文:35303030 30303030 30353535 33000000

將分組過的字符串數組逐步進行異或運算

異或流程

第 0組明文: 36303030 31313230 31383131 31343131

第 1組明文: 30303330 32303137 30393330 31303130

第 1組異或結果:06000300 03010307 01010201 00040001

第 2組明文:31303132 30313731 30323530 30303735

第 2組異或結果:37303232 33303436 31333731 30343734

第3組明文:35303030 30303030 30353535 33000000

與第2組密文異或:02000202 03000406 01060204 03343734

將最后異或結果轉化為16進制字符串

轉換為16進制

30323030 30323032 30333030 30343036 30313036 30323034 30333334 33373334

取前16位和后16位,前16位進行sm4加密,加密結果與后16位異或后再加密

前16位

30323030 30323032 30333030 30343036

后16位

30313036 30323034 30333334 33373334

前16位加密結果

B038A2B2 F3FFE3C8 AC60B377 C70C2DB1

與后16位異或結果

80099284 C3CDD3FC 9C538043 F43B1E85

再加密結果

1E80F373 40B0FEE6 2C81F356 AFB20BF1

取前16個字符作為mac值

mac值:1E80F37340B0FEE6

具體實現過程

準備工作

數據轉換工具類 TransferUtils.java

字符串轉換為16進制字符串

public static String StringToHexString(String str) {

String data = bytesToHexString(str.getBytes(), 32);

return data;

}

字節數組轉換為16進制字符串

/**

* 字節數組轉化為十六進制字符串 并按照len的倍數進行補"0"

* @param bytes 字節數據

* @param len 部位原則 不夠len倍數補"0"

* @return

*/

public static String bytesToHexString(byte[] bytes, int len) {

StringBuffer hexStr = new StringBuffer();

for (byte b : bytes) {

hexStr.append(String.format("%02x", new Integer(b & 0xff)));

}

//長度不滿32的整數倍 在后邊添加 "0"

while (hexStr.length() % len != 0) {

hexStr.append("0");

}

return hexStr.toString();

}

將字符串str 按照長度len 進行分組

/**

* 將字符串str 按照長度len 進行分組

* @param str 字符串

* @param len 每組字符長度

* @return

*/

public static String[] dataGrouping(String str, int len) {

int lenth = str.length() % len == 0 ? str.length() / len : str.length() / len + 1;

String[] data = new String[lenth];

for (int i = 0; i < lenth; i++) {

data[i] = str.substring(i * len, i * len + len);

}

return data;

}

將字符串數組進行異或運算

public static String handleXOrStringArr(String[] strs){

String result = "";

for (int i = 1;i < strs.length;i++){

if (i == 1){

result = xOr(strs[0],strs[1]);

}else {

result = xOr(strs[i],result);

}

}

return result;

}

異或運算

/**

* 異或運算

* @param s1

* @param s2

* @return

*/

public static String xOr(String s1, String s2) {

String data = IntArr2String(xOr(String2IntArr(s1),String2IntArr(s2)));

return data;

}

public static int [] xOr(int[] i1,int[] i2){

int[] xor = new int[i1.length];

for (int i = 0;i < i1.length & i < i2.length;i++){

xor[i] = i1[i]^i2[i];

}

return xor;

}

加密工具類

sm4加密

public static byte[] encodeSMS4(byte[] plaintext, byte[] key) {

byte[] ciphertext = new byte[plaintext.length];

int k = 0;

int plainLen = plaintext.length;

while (k + 16 <= plainLen) {

byte[] cellPlain = new byte[16];

for (int i = 0; i < 16; i++) {

cellPlain[i] = plaintext[k + i];

}

byte[] cellCipher = encode16(cellPlain, key);

for (int i = 0; i < cellCipher.length; i++) {

ciphertext[k + i] = cellCipher[i];

}

k += 16;

}

return ciphertext;

}

調用過程

將密鑰轉換為字節數組,將需要加密計算的字符串轉換為16進制字符串并補位

例如:

密鑰:"12345678901234567890123456789012"

待加密數據(字符串形式):

6000112018111411003020170930101010120171025000755000000005553

//將key轉換為字節數組

byte[] keys = TransformUtils.HexStringToByteArr(key);

//將加密數據轉換為16進制字符串

String hexData = TransformUtils.StringToHexString(data);

將轉換過的16字符串進行分組

//將數據分組 32位為一組

String[] dataGroup = TransformUtils.dataGrouping(hexData, 32);

將分組過的字符串數組逐步進行異或運算

//進行異或運算

String xorData = TransformUtils.handleXOrStringArr(dataGroup);

將最后異或結果轉化為16進制字符串

//將異或結果轉化為16進制字符串

String hexOxrData = TransformUtils.StringToHexString(xorData);

取前16字節和后16字節,前16字節進行sm4加密,加密結果與后16字節異或后再加密

//取前16字節和后16字節 兩個16進制位表示一個字節

String start32Bit = hexOxrData.substring(0,32);

String end32Bit = hexOxrData.substring(hexOxrData.length() - 32,hexOxrData.length());

//前16位進行首次加密

byte[] encodeSMS4_1 = SMS4.encodeSMS4(TransformUtils.HexStringToByteArr(start32Bit), keys);

//加密結果與后16位進行異或

String xOrEnd = TransformUtils.xOr(TransformUtils.bytesToHexString(encodeSMS4_1, 16), end32Bit);

//異或結果轉成字節數組

byte[] bytes = TransformUtils.HexStringToByteArr(xOrEnd);

//進行二次加密

byte[] resultByte = SMS4.encodeSMS4(bytes, keys);

//將加密結果轉換成16進制字符串 并取前八個字符作為mac值返回

String result = TransformUtils.bytesToHexString(resultByte, 16);

取前16個字符作為mac值

//取前8字節作為mac值返回

result = result.substring(0,16);

后記

此處是pos終端mac國密(sm4)算法,之前還有一個pos終端mac國際算法(雙倍長 3des),兩者的區別在于 分組的時候分組長度不太一樣,國際是16個16進制字符(8字節)分組,國密是32個16進制字符(16字節)分組,再有不同的地方就是加密算法不同,國密是sm4加密算法,國際是雙倍長3des加密算法,其他基本都是一樣的,這個加密算法也是根據需求可以進行更改的 ,比如改為RSA 或AES也是可以的,這個就需要雙方溝通了 統一加密算法就可以了

總結

以上是生活随笔為你收集整理的java mac pos_pos终端mac国密(sm4)算法(java实现)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。