mirror of
https://github.com/RfidResearchGroup/ChameleonBLEAPI.git
synced 2026-05-12 11:20:47 -07:00
Add files via upload
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
package com.proxgrind.chameleon.utils.security;
|
||||
|
||||
/**
|
||||
* crc16多项式算法
|
||||
*
|
||||
* @author eguid
|
||||
*/
|
||||
public class CRC16Utils {
|
||||
|
||||
/**
|
||||
* CRC16Utils-XMODEM算法(四字节)
|
||||
*
|
||||
* @param bytes
|
||||
* @return
|
||||
*/
|
||||
public static int crc16_ccitt_xmodem(byte[] bytes) {
|
||||
return crc16_ccitt_xmodem(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* CRC16Utils-XMODEM算法(四字节)
|
||||
*
|
||||
* @param bytes
|
||||
* @param offset
|
||||
* @param count
|
||||
* @return
|
||||
*/
|
||||
public static int crc16_ccitt_xmodem(byte[] bytes, int offset, int count) {
|
||||
int crc = 0x0000; // initial value
|
||||
int polynomial = 0x1021; // poly value
|
||||
for (int index = offset; index < count; index++) {
|
||||
byte b = bytes[index];
|
||||
for (int i = 0; i < 8; i++) {
|
||||
boolean bit = ((b >> (7 - i) & 1) == 1);
|
||||
boolean c15 = ((crc >> 15 & 1) == 1);
|
||||
crc <<= 1;
|
||||
if (c15 ^ bit)
|
||||
crc ^= polynomial;
|
||||
}
|
||||
}
|
||||
crc &= 0xffff;
|
||||
return crc;
|
||||
}
|
||||
|
||||
/**
|
||||
* CRC16Utils-XMODEM算法(两字节)
|
||||
*
|
||||
* @param bytes
|
||||
* @param offset
|
||||
* @param count
|
||||
* @return
|
||||
*/
|
||||
public static short crc16_ccitt_xmodem_short(byte[] bytes, int offset, int count) {
|
||||
return (short) crc16_ccitt_xmodem(bytes, offset, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* CRC16Utils-XMODEM算法(两字节)
|
||||
*
|
||||
* @param bytes
|
||||
*/
|
||||
public static short crc16_ccitt_xmodem_short(byte[] bytes) {
|
||||
return crc16_ccitt_xmodem_short(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.proxgrind.chameleon.utils.security;
|
||||
|
||||
public class CRC16_14443 {
|
||||
|
||||
//private static String LOG = CRC16_14443.class.getSimpleName();
|
||||
|
||||
public static final int CRC16_14443_A = 0x6363;
|
||||
public static final int CRC16_14443_B = 0xFFFF;
|
||||
|
||||
public static class Out {
|
||||
byte first;
|
||||
byte second;
|
||||
}
|
||||
|
||||
private static int updateCrc14443(byte b, int crc) {
|
||||
byte ch = (byte) (b ^ (byte) (crc & 0x00ff));
|
||||
ch = (byte) (ch ^ (ch << 4));
|
||||
return ((crc >> 8) ^ (ch << 8) ^ (ch << 3) ^ (ch >> 4));
|
||||
}
|
||||
|
||||
public static void computeCrc14443(int crc_type, byte[] bytes, int len, Out out) {
|
||||
out.first = 0;
|
||||
out.second = 0;
|
||||
if (len < 2) return;
|
||||
byte b;
|
||||
int res = crc_type;
|
||||
for (int i = 0; i < len; i++) {
|
||||
b = bytes[i];
|
||||
res = updateCrc14443(b, res);
|
||||
}
|
||||
/* ISO/IEC 13239 (formerly ISO/IEC 3309) */
|
||||
if (crc_type == CRC16_14443_B) res = ~res;
|
||||
out.first = (byte) (res & 0xFF);
|
||||
out.second = (byte) ((res >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
public static boolean checkCrc14443(int crc_type, byte[] bytes, int len) {
|
||||
if (len < 3) return false;
|
||||
Out out = new Out();
|
||||
computeCrc14443(crc_type, bytes, len - 2, out);
|
||||
byte crc1 = bytes[len - 2];
|
||||
byte crc2 = bytes[len - 1];
|
||||
/*Log.d(LOG, "计算的值1: " + HexUtil.toHexString(out.first));
|
||||
Log.d(LOG, "计算的值2: " + HexUtil.toHexString(out.second));
|
||||
Log.d(LOG, "传入的值1: " + HexUtil.toHexString(crc1));
|
||||
Log.d(LOG, "传入的值2: " + HexUtil.toHexString(crc2));*/
|
||||
return out.first == crc1 && out.second == crc2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
package com.proxgrind.chameleon.utils.security;
|
||||
|
||||
/**
|
||||
* CRC-8
|
||||
*
|
||||
* <table width="400px" border="1" cellpadding="0" cellspacing="0">
|
||||
* <tr>
|
||||
* <th>名称</th>
|
||||
* <th>多项式</th>
|
||||
* <th>初始值</th>
|
||||
* <th>异或值</th>
|
||||
* <th>Bit反转</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td> CRC-8</td>
|
||||
* <td align="center">0x07</td>
|
||||
* <td align="center">0x00</td>
|
||||
* <td align="center">0x00</td>
|
||||
* <td align="center">MSB First</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td> CRC-8/DARC</td>
|
||||
* <td align="center">0x39</td>
|
||||
* <td align="center">0x00</td>
|
||||
* <td align="center">0x00</td>
|
||||
* <td align="center">LSB First</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td> CRC-8/ITU</td>
|
||||
* <td align="center">0x07</td>
|
||||
* <td align="center">0x00</td>
|
||||
* <td align="center">0x55</td>
|
||||
* <td align="center">MSB First</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td> CRC-8/MAXIM</td>
|
||||
* <td align="center">0x31</td>
|
||||
* <td align="center">0x00</td>
|
||||
* <td align="center">0x00</td>
|
||||
* <td align="center">LSB First</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td> CRC-8/ROHC</td>
|
||||
* <td align="center">0x07</td>
|
||||
* <td align="center">0xFF</td>
|
||||
* <td align="center">0x00</td>
|
||||
* <td align="center">LSB First</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* @author unnamed
|
||||
*/
|
||||
public class CRC8Utils {
|
||||
|
||||
/**
|
||||
* CRC-8
|
||||
*
|
||||
* <table width="400px" border="1" cellpadding="0" cellspacing="0">
|
||||
* <tr>
|
||||
* <th>多项式</th>
|
||||
* <th>初始值</th>
|
||||
* <th>异或值</th>
|
||||
* <th>Bit反转</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td align="center">0x07</td>
|
||||
* <td align="center">0x00</td>
|
||||
* <td align="center">0x00</td>
|
||||
* <td align="center">MSB First</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* @param source
|
||||
* @param offset
|
||||
* @param length
|
||||
* @return
|
||||
*/
|
||||
public static int CRC8(byte[] source, int offset, int length) {
|
||||
int wCRCin = 0x00;
|
||||
int wCPoly = 0x07;
|
||||
for (int i = offset, cnt = offset + length; i < cnt; i++) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
boolean bit = ((source[i] >> (7 - j) & 1) == 1);
|
||||
boolean c07 = ((wCRCin >> 7 & 1) == 1);
|
||||
wCRCin <<= 1;
|
||||
if (c07 ^ bit)
|
||||
wCRCin ^= wCPoly;
|
||||
}
|
||||
}
|
||||
wCRCin &= 0xFF;
|
||||
return wCRCin ^= 0x00;
|
||||
}
|
||||
|
||||
/**
|
||||
* CRC-8/DARC
|
||||
*
|
||||
* <table width="400px" border="1" cellpadding="0" cellspacing="0">
|
||||
* <tr>
|
||||
* <th>多项式</th>
|
||||
* <th>初始值</th>
|
||||
* <th>异或值</th>
|
||||
* <th>Bit反转</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td align="center">0x39</td>
|
||||
* <td align="center">0x00</td>
|
||||
* <td align="center">0x00</td>
|
||||
* <td align="center">LSB First</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* @param source
|
||||
* @param offset
|
||||
* @param length
|
||||
* @return
|
||||
*/
|
||||
public static int CRC8_DARC(byte[] source, int offset, int length) {
|
||||
int wCRCin = 0x00;
|
||||
// Integer.reverse(0x39) >>> 24
|
||||
int wCPoly = 0x9C;
|
||||
for (int i = offset, cnt = offset + length; i < cnt; i++) {
|
||||
wCRCin ^= ((long) source[i] & 0xFF);
|
||||
for (int j = 0; j < 8; j++) {
|
||||
if ((wCRCin & 0x01) != 0) {
|
||||
wCRCin >>= 1;
|
||||
wCRCin ^= wCPoly;
|
||||
} else {
|
||||
wCRCin >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return wCRCin ^= 0x00;
|
||||
}
|
||||
|
||||
/**
|
||||
* CRC-8/ITU
|
||||
*
|
||||
* <table width="400px" border="1" cellpadding="0" cellspacing="0">
|
||||
* <tr>
|
||||
* <th>多项式</th>
|
||||
* <th>初始值</th>
|
||||
* <th>异或值</th>
|
||||
* <th>Bit反转</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td align="center">0x07</td>
|
||||
* <td align="center">0x00</td>
|
||||
* <td align="center">0x55</td>
|
||||
* <td align="center">MSB First</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* @param source
|
||||
* @param offset
|
||||
* @param length
|
||||
* @return
|
||||
*/
|
||||
public static int CRC8_ITU(byte[] source, int offset, int length) {
|
||||
int wCRCin = 0x00;
|
||||
int wCPoly = 0x07;
|
||||
for (int i = offset, cnt = offset + length; i < cnt; i++) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
boolean bit = ((source[i] >> (7 - j) & 1) == 1);
|
||||
boolean c07 = ((wCRCin >> 7 & 1) == 1);
|
||||
wCRCin <<= 1;
|
||||
if (c07 ^ bit)
|
||||
wCRCin ^= wCPoly;
|
||||
}
|
||||
}
|
||||
wCRCin &= 0xFF;
|
||||
return wCRCin ^= 0x55;
|
||||
}
|
||||
|
||||
/**
|
||||
* CRC-8/MAXIM
|
||||
*
|
||||
* <table width="400px" border="1" cellpadding="0" cellspacing="0">
|
||||
* <tr>
|
||||
* <th>多项式</th>
|
||||
* <th>初始值</th>
|
||||
* <th>异或值</th>
|
||||
* <th>Bit反转</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td align="center">0x31</td>
|
||||
* <td align="center">0x00</td>
|
||||
* <td align="center">0x00</td>
|
||||
* <td align="center">LSB First</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* @param source
|
||||
* @param offset
|
||||
* @param length
|
||||
* @return
|
||||
*/
|
||||
public static int CRC8_MAXIM(byte[] source, int offset, int length) {
|
||||
int wCRCin = 0x00;
|
||||
// Integer.reverse(0x31) >>> 24
|
||||
int wCPoly = 0x8C;
|
||||
for (int i = offset, cnt = offset + length; i < cnt; i++) {
|
||||
wCRCin ^= ((long) source[i] & 0xFF);
|
||||
for (int j = 0; j < 8; j++) {
|
||||
if ((wCRCin & 0x01) != 0) {
|
||||
wCRCin >>= 1;
|
||||
wCRCin ^= wCPoly;
|
||||
} else {
|
||||
wCRCin >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return wCRCin ^= 0x00;
|
||||
}
|
||||
|
||||
/**
|
||||
* CRC-8/ROHC
|
||||
*
|
||||
* <table width="400px" border="1" cellpadding="0" cellspacing="0">
|
||||
* <tr>
|
||||
* <th>多项式</th>
|
||||
* <th>初始值</th>
|
||||
* <th>异或值</th>
|
||||
* <th>Bit反转</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td align="center">0x07</td>
|
||||
* <td align="center">0xFF</td>
|
||||
* <td align="center">0x00</td>
|
||||
* <td align="center">LSB First</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* @param source
|
||||
* @param offset
|
||||
* @param length
|
||||
* @return
|
||||
*/
|
||||
public static int CRC8_ROHC(byte[] source, int offset, int length) {
|
||||
int wCRCin = 0xFF;
|
||||
// Integer.reverse(0x07) >>> 24
|
||||
int wCPoly = 0xE0;
|
||||
for (int i = offset, cnt = offset + length; i < cnt; i++) {
|
||||
wCRCin ^= ((long) source[i] & 0xFF);
|
||||
for (int j = 0; j < 8; j++) {
|
||||
if ((wCRCin & 0x01) != 0) {
|
||||
wCRCin >>= 1;
|
||||
wCRCin ^= wCPoly;
|
||||
} else {
|
||||
wCRCin >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return wCRCin ^= 0x00;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
package com.proxgrind.chameleon.utils.security;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
|
||||
import java.security.*;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* 非对称加密算法RSA算法组件
|
||||
* 非对称算法一般是用来传送对称加密算法的密钥来使用的,相对于DH算法,RSA算法只需要一方构造密钥,不需要
|
||||
* 大费周章的构造各自本地的密钥对了。DH算法只能算法非对称算法的底层实现。而RSA算法算法实现起来较为简单
|
||||
*
|
||||
* @author kongqz
|
||||
*/
|
||||
public class RSAUtils {
|
||||
|
||||
//非对称密钥算法
|
||||
public static final String KEY_ALGORITHM = "RSA";
|
||||
/**
|
||||
* 密钥长度,DH算法的默认密钥长度是1024
|
||||
* 密钥长度必须是64的倍数,在512到65536位之间
|
||||
*/
|
||||
private static final int KEY_SIZE = 1024;
|
||||
//公钥
|
||||
private static final String PUBLIC_KEY = "RSAPublicKey";
|
||||
//私钥
|
||||
private static final String PRIVATE_KEY = "RSAPrivateKey";
|
||||
|
||||
/**
|
||||
* 初始化密钥对
|
||||
*
|
||||
* @return Map 甲方密钥的Map
|
||||
*/
|
||||
public static Map<String, Object> initKey() throws Exception {
|
||||
//实例化密钥生成器
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
|
||||
//初始化密钥生成器
|
||||
keyPairGenerator.initialize(KEY_SIZE);
|
||||
//生成密钥对
|
||||
KeyPair keyPair = keyPairGenerator.generateKeyPair();
|
||||
//甲方公钥
|
||||
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
|
||||
//甲方私钥
|
||||
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
|
||||
//将密钥存储在map中
|
||||
Map<String, Object> keyMap = new HashMap<>();
|
||||
keyMap.put(PUBLIC_KEY, publicKey);
|
||||
keyMap.put(PRIVATE_KEY, privateKey);
|
||||
return keyMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 私钥加密
|
||||
*
|
||||
* @param data 待加密数据
|
||||
* @param key 密钥
|
||||
* @return byte[] 加密数据
|
||||
*/
|
||||
public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception {
|
||||
|
||||
//取得私钥
|
||||
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
//生成私钥
|
||||
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
|
||||
//数据加密
|
||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
|
||||
return cipher.doFinal(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 公钥加密
|
||||
*
|
||||
* @param data 待加密数据
|
||||
* @param key 密钥
|
||||
* @return byte[] 加密数据
|
||||
*/
|
||||
public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception {
|
||||
|
||||
//实例化密钥工厂
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
//初始化公钥
|
||||
//密钥材料转换
|
||||
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
|
||||
//产生公钥
|
||||
PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);
|
||||
//数据加密
|
||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
|
||||
return cipher.doFinal(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 私钥解密
|
||||
*
|
||||
* @param data 待解密数据
|
||||
* @param key 密钥
|
||||
* @return byte[] 解密数据
|
||||
*/
|
||||
public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception {
|
||||
//取得私钥
|
||||
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
//生成私钥
|
||||
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
|
||||
//数据解密
|
||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
return cipher.doFinal(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 公钥解密
|
||||
*
|
||||
* @param data 待解密数据
|
||||
* @param key 密钥
|
||||
* @return byte[] 解密数据
|
||||
*/
|
||||
public static byte[] decryptByPublicKey(byte[] data, byte[] key) throws Exception {
|
||||
//实例化密钥工厂
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
//初始化公钥
|
||||
//密钥材料转换
|
||||
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
|
||||
//产生公钥
|
||||
PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);
|
||||
//数据解密
|
||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, pubKey);
|
||||
return cipher.doFinal(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得私钥
|
||||
*
|
||||
* @param keyMap 密钥map
|
||||
* @return byte[] 私钥
|
||||
*/
|
||||
public static byte[] getPrivateKey(Map<String, Object> keyMap) {
|
||||
Key key = (Key) keyMap.get(PRIVATE_KEY);
|
||||
return key.getEncoded();
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得公钥
|
||||
*
|
||||
* @param keyMap 密钥map
|
||||
* @return byte[] 公钥
|
||||
*/
|
||||
public static byte[] getPublicKey(Map<String, Object> keyMap) throws Exception {
|
||||
Key key = (Key) keyMap.get(PUBLIC_KEY);
|
||||
return key.getEncoded();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user