大家好,我这里有个java加密方法,我想写成C#的,本人能力有限,希望大神们帮帮吗,写成C#方法
直接上java 代码
import java.security.Key;java?加密方法?C#?
import java.util.Vector;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
public class KeyTest {
// 密钥算法
public static final String KEY_ALGORITHM = "DES";
// 加密/解密算法/工作模式/填充方式(无填充)
public static final String CIPHER_ALGORITHM4CCB = "DES/CBC/NOPadding";
// CBC向量(标准DESCBC向量无偏移)
public static final byte[] EncryptionIV4CCB = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
// 用于建立十六进制字符的输出的小写字符数组
private static final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
// 用于建立十六进制字符的输出的大写字符数组
private static final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
/**
* @param args
* @throws Throwable
*/
public static void main(String[] args) throws Throwable {
// 主密钥
String primaryKey = "f3cea8825c3610ea";
byte[] primaryKey2 = hexStringToByte(primaryKey);
// pinkey
String pinkeyEn = "a60446f56d7a87db";
byte[] pinkeyEn2 = hexStringToByte(pinkeyEn);
// mackey
String mackeyEn = "555ac13972cb897b";
byte[] mackeyEn2 = hexStringToByte(mackeyEn);
System.out.println("解密后的pinkey:" + encodeHexStr(getDESDecrypt4CCB(pinkeyEn2, primaryKey2)));
System.out.println("解密后的mackey:" + encodeHexStr(getDESDecrypt4CCB(mackeyEn2, primaryKey2)));
// pinkeyuse
String pinkeyUse = encodeHexStr(getDESDecrypt4CCB(pinkeyEn2, primaryKey2));
// mackeyuse
String macUse = encodeHexStr(getDESDecrypt4CCB(mackeyEn2, primaryKey2));
StringBuffer xmlSB = new StringBuffer();
// xmlSB.append("20130709105110048141238980555339<?xml version="1.0" encoding = "GBK"?><Req><KeyID>01</KeyID><PINKey>a60446f56d7a87db</PINKey><MacKey>555ac13972cb897b</MacKey></Req>");
xmlSB.append("20130712105110048141238980555339<?xml version="1.0" encoding = "GBK"?><Req><KeyID>01</KeyID><PINKey>a60446f56d7a87db</PINKey><MacKey>555ac13972cb897b</MacKey></Req>");
// ----------------------------------------
String mac = encodeHexStr(tCountMAC4CCB(hexStringToByte(macUse), xmlSB.toString().getBytes("GBK"), 0, -1));
System.out.println("加密后的mac校验字段:" + mac);
String reqXmlBodyMsg = "<?xml version="1.0" encoding = "GBK"?><Req><KeyID>01</KeyID><PINKey>a60446f56d7a87db</PINKey><MacKey>555ac13972cb897b</MacKey></Req>";
byte[] encryptedReqXmlBodyMsg = fillMessageBody4CCB(hexStringToByte(pinkeyUse), reqXmlBodyMsg.getBytes("GBK"), 0, -1);
System.out.println("加密后的报文体(不含请求报文头):" + encodeHexStr(encryptedReqXmlBodyMsg));
}
public static byte[] hexStringToByte(String hex) {
hex = hex.toUpperCase();
int len = (hex.length() / 2);
byte[] result = new byte[len];
char[] achar = hex.toCharArray();
for (int i = 0; i < len; i++) {
int pos = i * 2;
result[i] = (byte) (hexToByte(achar[pos]) << 4 | hexToByte(achar[pos + 1]));
}
return result;
}
private static byte hexToByte(char c) {
byte b = (byte) "0123456789ABCDEF".indexOf(c);
return b;
}
/**
* 单DES解密算法
*
* @param data
* 待解密数据
* @param key
* 密钥
* @return byte[] 解密后的数据
* @throws Exception
*/
public static byte[] getDESDecrypt4CCB(byte[] encryptStr, byte[] key) throws Exception {
try {
DESKeySpec dks = new DESKeySpec(key);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
Key secretKey = keyFactory.generateSecret(dks);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM4CCB);
IvParameterSpec param = new IvParameterSpec(EncryptionIV4CCB);
cipher.init(Cipher.DECRYPT_MODE, secretKey, param);
return cipher.doFinal(encryptStr);
} catch (Exception e) {
throw new Exception("DES解密参数[" + encryptStr + "]发生错误,解密key为[" + key + "]", e);
}
}
/**
* 将字节数组转换为十六进制字符串
*
* @param data
* byte[]
* @return 十六进制String
*/
public static String encodeHexStr(byte[] data) {
return encodeHexStr(data, true);
}
/**
* 将字节数组转换为十六进制字符串
*
* @param data
* byte[]
* @param toLowerCase
* <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式
* @return 十六进制String
*/
public static String encodeHexStr(byte[] data, boolean toLowerCase) {
return encodeHexStr(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
}
/**
* 将字节数组转换为十六进制字符串
*
* @param data
* byte[]
* @param toDigits
* 用于控制输出的char[]
* @return 十六进制String
*/
protected static String encodeHexStr(byte[] data, char[] toDigits) {
return new String(encodeHex(data, toDigits));
}
/**
* 将字节数组转换为十六进制字符数组
*
* @param data
* byte[]
* @param toDigits
* 用于控制输出的char[]
* @return 十六进制char[]
*/
protected static char[] encodeHex(byte[] data, char[] toDigits) {
int l = data.length;
char[] out = new char[l << 1];
// two characters form the hex value.
for (int i = 0, j = 0; i < l; i++) {
out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
out[j++] = toDigits[0x0F & data[i]];
}
return out;
}
/**
* 将Block[8]和原始数据按位XOR
*
* @param tKey
* DES密钥key
* @param tBuffer
* @param iOffset
* @param iLength
* @return byte[]
* @throws Exception
*/
public static byte[] tCountMAC4CCB(byte[] tKey, byte[] tBuffer, int iOffset, int iLength) throws Exception {
byte[] tResult = null;
Vector<byte[]> vctBlk = new Vector<byte[]>();
byte[] tTmp, tBlk, tXor, tDes;
int iNum, iLen, iPos, iN, i;
if (tKey == null || tBuffer == null)
return tResult;
if (iOffset < 0)
iOffset = 0;
if (iLength < 0)
iLength = tBuffer.length - iOffset;
// 拆分数据(8字节块/Block)
iLen = 0;
iPos = iOffset;
while (iLen < iLength && iPos < tBuffer.length) {
tBlk = new byte[8];
for (i = 0; i < tBlk.length; i++)
tBlk[i] = (byte) 0; // clear(0x00)
for (i = 0; i < tBlk.length && iLen < iLength && iPos < tBuffer.length; i++) {
tBlk[i] = tBuffer[iPos++];
iLen++;
}
vctBlk.addElement(tBlk); // store (back)
}
// 循环计算(XOR + DES)
tDes = new byte[8]; // 初始数据 byte[8] {0x00, 0x00.....}
for (i = 0; i < tDes.length; i++)
tDes[i] = (byte) 0; // clear(0x00)
iNum = vctBlk.size();
for (iN = 0; iN < iNum; iN++) {
tBlk = (byte[]) vctBlk.elementAt(iN);
if (tBlk == null)
continue;
tXor = new byte[Math.min(tDes.length, tBlk.length)];
for (i = 0; i < tXor.length; i++)
tXor[i] = (byte) (tDes[i] ^ tBlk[i]); // 异或(Xor)
tTmp = getDESEncrypt4CCB(tXor, tKey); // 单DES加密
for (i = 0; i < tDes.length; i++)
tDes[i] = (byte) 0; // clear
for (i = 0; i < Math.min(tDes.length, tTmp.length); i++)
tDes[i] = tTmp[i]; // copy / transfer
}
vctBlk.removeAllElements(); // clear
tResult = tDes;
return tResult;
}
/**
* 单DES加密算法
*
* @param data
* 待加密数据
* @param key
* 密钥
* @return byte[] 加密后的数据
* @throws Exception
*/
public static byte[] getDESEncrypt4CCB(byte[] encryptStr, byte[] key) throws Exception {
try {
DESKeySpec dks = new DESKeySpec(key);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
Key k = keyFactory.generateSecret(dks);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM4CCB);
IvParameterSpec param = new IvParameterSpec(EncryptionIV4CCB);
cipher.init(Cipher.ENCRYPT_MODE, k, param);
return cipher.doFinal(encryptStr);
} catch (Exception e) {
throw new Exception("DES加密参数[" + encryptStr + "]发生错误,加密key为[" + key + "]", e);
}
}
/**
* 报文体填充加密
*
* 将Block[8]和原始数据按位XOR
*
* @param tKey
* DES密钥key
* @param tBuffer
* @param iOffset
* @param iLength
* @return byte[]
*/
public static byte[] fillMessageBody4CCB(byte[] tKey, byte[] tBuffer, int iOffset, int iLength) {
byte[] tResult = null;
if (tKey == null || tBuffer == null)
return tResult;
if (iOffset < 0)
iOffset = 0;
if (iLength < 0)
iLength = tBuffer.length - iOffset;
int len = tBuffer.length / 8;
int iLen = tBuffer.length % 8;
if (iLen != 0) {
len = len + 1;
}
tResult = new byte[len * 8];
int i = 0;
for (i = 0; i < tBuffer.length; i++) {
tResult[i] = tBuffer[i];
}
if (iLen != 0) {
for (int j = 0; j < 8 - iLen; j++) {
tResult[i++] = (byte) 0;
}
}
try {
tResult = getDESEncrypt4CCB(tResult, tKey);
} catch (Exception e) {
e.printStackTrace();
} // DES加密
return tResult;
}
}
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
namespace posclass
{
public static class desmac
{
//将十六进制的字符串转换成字节数组
public static byte[] hex2byte(string hex)
{
byte[] result;
if (hex.Count() % 2 == 1)
{
hex += "0";
}
int i;
int hexlen;
hexlen = hex.Count() / 2;
result = new byte[hexlen];
for (i = 0; i < hexlen; i++)
{
result[i] = (byte)Convert.ToUInt32(hex.Substring(i * 2, 2), 16);
}
return result;
}
//将字节数组转换成十六进制字符串
public static string byte2hex(byte[] bytes)
{
StringBuilder result = new StringBuilder();
foreach (byte bitem in bytes)
{
result.Append(bitem.ToString("X2"));
}
return result.ToString();
}
//将字节数组转换成二进制字符串
public static string byte2bin(byte[] bytes)
{
StringBuilder result = new StringBuilder();
foreach (byte bitem in bytes)
{
result.Append(Convert.ToString(bitem, 2).PadLeft(8, '0'));
}
return result.ToString();
}
//将字节数组转换成域位序号,即位图数组
public static int[] byte2key(byte[] bytes)
{
int[] keylist = new int[256];
int i = 0;
int j = 0;
int k = 0;
int left;
int fac;
foreach (byte bytekey in bytes)
{
j = 1;
left = (int)bytekey;
fac = 128;
while (left > 0)
{
if (left >= fac)
{
keylist[k] = i * 8 + j;
left -= fac;
k++;
}
fac /= 2;
j++;
}
i++;
}
Array.Resize(ref keylist, k);
return keylist;
}
public static int[] byte2keyb(byte[] bytes)
{
StringBuilder bin = new StringBuilder();
foreach (byte bitem in bytes)
{
bin.Append(Convert.ToString(bitem, 2).PadLeft(8, '0'));
}
string strbin = bin.ToString();
int[] keylist = new int[256];
int i = 0;
int key = strbin.IndexOf('1');
while (key >= 0)
{
key++;
keylist[i] = key;
i++;
key = strbin.IndexOf('1', key);
}
Array.Resize(ref keylist, i);
return keylist;
}
//将十六进制字符串转换成二进制字符串
public static string hex2bin(string hex)
{
return byte2bin(hex2byte(hex));
}
//将字节数组用方括号连接成字符串
public static string bytetostring(byte[] bytes)
{
string result = "";
int bytecount = bytes.Count();
int i;
for (i = 0; i < bytecount; i++)
{
if (i > 0 && i % 20 == 0)
result += "\n";
result += "[" + Convert.ToString(bytes[i], 16).PadLeft(2, '0') + "]";
}
return result;
}
//将字节数组进行异或运算,结果数组长度以参数中短的字节数组为准
public static byte[] bytexor(byte[] bytea, byte[] byteb)
{
int lena = bytea.Count();
int lenb = byteb.Count();
int lenresult;
if (lena > lenb)
{
lenresult = lenb;
}
else
{
lenresult = lena;
}
byte[] byteresult = new byte[lenresult];
int i;
for (i = 0; i < lenresult; i++)
{
byteresult[i] = (byte)(bytea[i] ^ byteb[i]);
}
return byteresult;
}
//对十六进制的字符串进行异或运算(要求做异或的字符串必须长度一致,否则按短的字符串标准做异或)
public static string hexxor(string hexa, string hexb)
{
byte[] bytea = hex2byte(hexa);
byte[] byteb = hex2byte(hexb);
byte[] byteresult = bytexor(bytea, byteb);
return byte2hex(byteresult);
}
//DES加解密,0为加密(默认),1为解密
public static byte[] desende(byte[] key, byte[] data, int type = 0)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
CryptoStream desStream;
des.Key = key;
des.Mode = CipherMode.ECB;
des.Padding = PaddingMode.None;
MemoryStream streamout = new MemoryStream();
if (type == 0)
desStream = new CryptoStream(streamout, des.CreateEncryptor(), CryptoStreamMode.Write);
else
desStream = new CryptoStream(streamout, des.CreateDecryptor(), CryptoStreamMode.Write);
desStream.Write(data, 0, data.Count());
desStream.FlushFinalBlock();
desStream.Dispose();
return streamout.ToArray();
}
//MAC值计算
public static byte[] getmacbyte(byte[] mak, byte[] mab)
{
int mablen = mab.Length;
int i = 0;
byte[] tma = new byte[8];
byte[] tmb = new byte[8];
while (i < mablen)
{
tmb = new byte[8];
if (mablen - i > 8)
Array.Copy(mab, i, tmb, 0, 8);
else
Array.Copy(mab, i, tmb, 0, mablen - i);
tma = bytexor(tma, tmb);
i += 8;
}
//将字符串按照十六进制字符串展开
byte[] exptma = Encoding.UTF8.GetBytes(desmac.byte2hex(tma));
//tma为前半段
Array.Copy(exptma, 0, tma, 0, 8);
//tmb为后半段
Array.Copy(exptma, 8, tmb, 0, 8);
//前半段tma用mak加密
tma = desende(mak, tma);
//与后半段tmb异或
tma = bytexor(tma, tmb);
//异或结果tma用mak加密
tma = desende(mak, tma);
//加密结果再做十六进制展开
exptma = Encoding.UTF8.GetBytes(desmac.byte2hex(tma));
//返回展开后前半段
Array.Copy(exptma, 0, tma, 0, 8);
return tma;
}
//签到返回报文的62域中提取PIK,MAK(所有参数都为十六进制表示)
public static int getkey(byte[] enkey, byte[] tmk, ref byte[] pik, ref byte[] mak)
{
byte[] enpik = new byte[8];
byte[] pikck = new byte[4];
byte[] enmak = new byte[8];
byte[] makck = new byte[4];
Array.Copy(enkey, 0, enpik, 0, 8);
Array.Copy(enkey, 8, pikck, 0, 4);
Array.Copy(enkey, 12, enmak, 0, 8);
Array.Copy(enkey, 20, makck, 0, 4);
pik = desende(tmk, enpik, 1);
mak = desende(tmk, enmak, 1);
byte[] datacheck = new byte[8];
byte[] keycheck = new byte[4];
Array.Copy(desende(pik, datacheck), 0, keycheck, 0, 4);
if (!pikck.Equals(keycheck))
return 1;
Array.Copy(desende(mak, datacheck), 0, keycheck, 0, 4);
if (!makck.Equals(keycheck))
return 2;
return 0;
}
//计算PINBLOCK
public static string getpb(string pan, string pin)
{
string pinpart = pin.Count().ToString().PadLeft(2, '0') + pin.PadRight(14, 'F');
string panpart = pan.Substring(pan.Count() - 13, 12).PadLeft(16, '0');
return hexxor(pinpart, panpart);
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
public class KeyTest
{
// 密钥算法
public const string KEY_ALGORITHM = "DES";
// 加密/解密算法/工作模式/填充方式(无填充)
public const string CIPHER_ALGORITHM4CCB = "DES/CBC/NOPadding";
// CBC向量(标准DESCBC向量无偏移)
public static readonly sbyte[] EncryptionIV4CCB = new sbyte[] {0, 0, 0, 0, 0, 0, 0, 0};
// 用于建立十六进制字符的输出的小写字符数组
private static readonly char[] DIGITS_LOWER = new char[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
// 用于建立十六进制字符的输出的大写字符数组
private static readonly char[] DIGITS_UPPER = new char[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
/// <param name="args"> </param>
/// <exception cref="Throwable"> </exception>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public static void main(String[] args) throws Throwable
public static void Main(string[] args)
{
// 主密钥
string primaryKey = "f3cea8825c3610ea";
sbyte[] primaryKey2 = hexStringToByte(primaryKey);
// pinkey
string pinkeyEn = "a60446f56d7a87db";
sbyte[] pinkeyEn2 = hexStringToByte(pinkeyEn);
// mackey
string mackeyEn = "555ac13972cb897b";
sbyte[] mackeyEn2 = hexStringToByte(mackeyEn);
Console.WriteLine("解密后的pinkey:" + encodeHexStr(getDESDecrypt4CCB(pinkeyEn2, primaryKey2)));
Console.WriteLine("解密后的mackey:" + encodeHexStr(getDESDecrypt4CCB(mackeyEn2, primaryKey2)));
// pinkeyuse
string pinkeyUse = encodeHexStr(getDESDecrypt4CCB(pinkeyEn2, primaryKey2));
// mackeyuse
string macUse = encodeHexStr(getDESDecrypt4CCB(mackeyEn2, primaryKey2));
StringBuilder xmlSB = new StringBuilder();
// xmlSB.append("20130709105110048141238980555339<?xml version="1.0" encoding = "GBK"?><Req><KeyID>01</KeyID><PINKey>a60446f56d7a87db</PINKey><MacKey>555ac13972cb897b</MacKey></Req>");
xmlSB.Append("20130712105110048141238980555339<?xml version="1.0" encoding = "GBK"?><Req><KeyID>01</KeyID><PINKey>a60446f56d7a87db</PINKey><MacKey>555ac13972cb897b</MacKey></Req>");
// ----------------------------------------
string mac = encodeHexStr(tCountMAC4CCB(hexStringToByte(macUse), xmlSB.ToString().GetBytes("GBK"), 0, -1));
Console.WriteLine("加密后的mac校验字段:" + mac);
string reqXmlBodyMsg = "<?xml version="1.0" encoding = "GBK"?><Req><KeyID>01</KeyID><PINKey>a60446f56d7a87db</PINKey><MacKey>555ac13972cb897b</MacKey></Req>";
sbyte[] encryptedReqXmlBodyMsg = fillMessageBody4CCB(hexStringToByte(pinkeyUse), reqXmlBodyMsg.GetBytes("GBK"), 0, -1);
Console.WriteLine("加密后的报文体(不含请求报文头):" + encodeHexStr(encryptedReqXmlBodyMsg));
}
public static sbyte[] hexStringToByte(string hex)
{
hex = hex.ToUpper();
int len = (hex.Length / 2);
sbyte[] result = new sbyte[len];
char[] achar = hex.ToCharArray();
for (int i = 0; i < len; i++)
{
int pos = i * 2;
result[i] = (sbyte)(hexToByte(achar[pos]) << 4
[解决办法]
hexToByte(achar[pos + 1]));
}
return result;
}
private static sbyte hexToByte(char c)
{
sbyte b = (sbyte) "0123456789ABCDEF".IndexOf(c);
return b;
}
/// <summary>
/// 单DES解密算法
/// </summary>
/// <param name="data">
/// 待解密数据 </param>
/// <param name="key">
/// 密钥 </param>
/// <returns> byte[] 解密后的数据 </returns>
/// <exception cref="Exception"> </exception>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public static byte[] getDESDecrypt4CCB(byte[] encryptStr, byte[] key) throws Exception
public static sbyte[] getDESDecrypt4CCB(sbyte[] encryptStr, sbyte[] key)
{
try
{
DESKeySpec dks = new DESKeySpec(key);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
Key secretKey = keyFactory.generateSecret(dks);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM4CCB);
IvParameterSpec param = new IvParameterSpec(EncryptionIV4CCB);
cipher.init(Cipher.DECRYPT_MODE, secretKey, param);
return cipher.doFinal(encryptStr);
}
catch (Exception e)
{
throw new Exception("DES解密参数[" + encryptStr + "]发生错误,解密key为[" + key + "]", e);
}
}