TDes

?package https://www.360docs.net/doc/7b16182854.html,.EDEP;

import javacard.framework.JCSystem;
import javacard.framework.Util;
import javacard.security.DESKey;
import javacard.security.KeyBuilder;
//import javacard.security.KeyBuilder;
import javacardx.crypto.Cipher;

public class TDes {
DESKey singleDeskey,tripleDesKey,macKey;
Cipher cp;
//byte[] bNKey;
byte[] bTmpKey;
byte[] bRes;
byte[] bMidData;
boolean bDebug;
public TDes( DESKey aKey,Cipher acp)
{
key = aKey;
cp = acp;
bDebug = true;
bTmpKey = JCSystem.makeTransientByteArray((short)16, JCSystem.CLEAR_ON_DESELECT);
bRes = JCSystem.makeTransientByteArray((short)16, JCSystem.CLEAR_ON_DESELECT);
bMidData = JCSystem.makeTransientByteArray((short)16, JCSystem.CLEAR_ON_DESELECT);
//byte[] bNKey = JCSystem.makeTransientByteArray((short)128, JCSystem.CLEAR_ON_DESELECT);
}
public short TripleDes(byte[] bKey,short nKeyOffset,short nKeyLen, byte[] bData ,short nDataOffset,short nDataLen,byte EncryptOrDecrypt,byte[]bOutBuf,short OutOffset)
{
//byte[] bNKey =new byte[nDataLen];
//byte[] bNKey = JCSystem.makeTransientByteArray(nDataLen, JCSystem.CLEAR_ON_DESELECT);
if( MyDebug.NewObject){
if( nKeyLen == 8)
key = (DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES, false);
else
key = (DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_2KEY, false);
cp = Cipher.getInstance(Cipher.ALG_DES_ECB_ISO9797_M1 , false);
}
if(nKeyLen ==8){
Util.arrayCopyNonAtomic(bKey, (short)nKeyOffset, bTmpKey, (short)0, (short)8);
Util.arrayCopyNonAtomic(bKey, (short)nKeyOffset, bTmpKey, (short)8, (short)8);
}
else{
Util.arrayCopyNonAtomic(bKey, (short)nKeyOffset, bTmpKey, (short)0, nKeyLen);
}
key.setKey(bTmpKey, (short)0);
if(EncryptOrDecrypt == 0x01){//加密
cp.init(key, Cipher.MODE_ENCRYPT);
}
else{
cp.init(key, Cipher.MODE_DECRYPT);
}
cp.doFinal(bData, nDataOffset, nDataLen, bOutBuf, OutOffset);

return (nDataLen ==8)?(nDataLen):((short)((nDataLen+8)/8 *8));
}
/**
* 计算离散子密钥
* @param bKey --主密钥
* @param nKeyOffset --主密钥偏移量
* @param bData --分散因子
* @param nDataOffset --分散因子的偏移量
* @param bSonKey --得到的离散子密钥
* @param bSonOffset -存放离散子密钥的偏移量
*/
public void CreateSonKey( byte[] bKey,short nKeyOffset, byte[] bData,short nDataOffset,byte[] bSonKey,short bSonOffset)
{
short i;
Util.arrayFillNonAtomic(bTmpKey, (short)0, (short)16, (byte)0x00);
Util.arrayFillNonAtomic(bRes ,(short)0, (short)16, (byte)0x00);
if( MyDebug.NewObject){
key = (DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_2KEY, false);
cp = Cipher.getInstance(Cipher.ALG_DES_ECB_ISO9797_M1 , false);
}
key.setKey(bKey, (short)nKeyOffset);
cp.init(key, Cipher.MODE_ENCRYPT);
cp.doFinal(bData, (short)(nDataOffset), (short)8, bRes, (short)0);
for( i =

0;i < 8; i ++)
bSonKey[8+i] =(byte)( bData[nDataOffset+i] ^ 0xFF);
cp.doFinal(bSonKey, (short)(8), (short)8, bRes, (short)8);
Util.arrayCopyNonAtomic(bRes, (short)0, bSonKey, bSonOffset, (short)16);
if( MyDebug.ObjectDel)
JCSystem.requestObjectDeletion();
}
/*
public byte[] CreateSonKey( byte[] bKey, byte[] bData,short nDataOffset)
{
byte[] bSonKey =bTmpKey;
short i;
Util.arrayFillNonAtomic(bSonKey, (short)0,(short)16, (byte)0x00);
key =(DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_2KEY, false);
key.setKey(bKey, (short)0);
cp = Cipher.getInstance(Cipher.ALG_DES_ECB_ISO9797_M1, false);
cp.init(key, Cipher.MODE_ENCRYPT);
cp.doFinal(bData, (short)(nDataOffset), (short)8, bSonKey, (short)0);
for( i = 0;i < 8; i ++)
bSonKey[8+i] =(byte)( bData[nDataOffset+i] ^ 0xFF);
cp.doFinal(bSonKey, (short)(8), (short)8, bSonKey, (short)8);
return bSonKey;
}
*/

/**
* @category --计算过程子密钥
* @param bKey --主密钥
* @param nKeyOffset --主密钥偏移量
* @param nKeyLen --主密钥长度
* @param bData --过程因子
* @param nDataOffset --过程因子偏移量
* @param nDataLen --过程因子长度
* @param bSessKey --存放计算出的过程密钥
* @param nSessKeyOffset --存放过程密钥的偏移量
*/
public void CreateSessionKey(byte[] bKey,short nKeyOffset,short nKeyLen,byte[] bData,short nDataOffset,short nDataLen ,byte[] bSessKey,short nSessKeyOffset ){
//byte[] bSessKey = new byte[8];
//Util.arrayFillNonAtomic(bSessKey, (short)0,(short)8, (byte)0x00);
Util.arrayFillNonAtomic(bTmpKey, (short)0, (short)16, (byte)0x00);
Util.arrayFillNonAtomic(bRes ,(short)0, (short)16, (byte)0x00);
if( nKeyLen ==16){
//key =(DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_2KEY, false);
Util.arrayCopyNonAtomic(bKey, (short)nKeyOffset, bTmpKey, (short)0, nKeyLen);
}
else{
//key =(DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES, false);
Util.arrayCopyNonAtomic(bKey, (short)nKeyOffset, bTmpKey, (short)0, (short)8);
Util.arrayCopyNonAtomic(bKey, (short)nKeyOffset, bTmpKey, (short)8, (short)8);
}
if( MyDebug.NewObject){
key = (DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_2KEY, false);
cp = Cipher.getInstance(Cipher.ALG_DES_ECB_ISO9797_M1 , false);
}
key.setKey(bTmpKey, (short)0);
//cp = Cipher.getInstance(Cipher.ALG_DES_ECB_ISO9797_M1, false);
cp.init(key, Cipher.MODE_ENCRYPT);
cp.doFinal(bData, (short)(nDataOffset), (short)nDataLen, bRes, (short)0);

//return bSessKey;
Util.arrayCopyNonAtomic(bRes, (short)0, bSessKey, nSessKeyOffset, (short)8);
if( MyDebug.ObjectDel)
JCSystem.requestObjectDeletion();
}
/*
public byte[] CreatrSessionKey(byte[] bKey,short nKeyLen,byte[] bData,short nDataOffset,short nDataLen ){

byte[] bSessKey = new byte[8];
Util.arrayFillNon

Atomic(bSessKey, (short)0,(short)8, (byte)0x00);
if( nKeyLen ==16)
key =(DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_2KEY, false);
else
key =(DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES, false);
key.setKey(bKey, (short)0);
cp = Cipher.getInstance(Cipher.ALG_DES_ECB_ISO9797_M1, false);
cp.init(key, Cipher.MODE_ENCRYPT);
cp.doFinal(bData, (short)(nDataOffset), (short)nDataLen, bSessKey, (short)0);
return bSessKey;
}
*/
/**
* @category --Xor Key1 and Key2 ,generate new Key
* @param bKey1
* @param nKeyOffset1
* @param nKeyLen1
* @param bKey2
* @param nKeyOffset2
* @param nKeyLen2
* @param bXorKey
* @param nXorKeyOffset
* @return the new Key's Length
*/
public short KeyXor( byte[] bKey1,short nKeyOffset1, short nKeyLen1,byte[] bKey2,short nKeyOffset2,short nKeyLen2 , byte[] bXorKey,short nXorKeyOffset)
{
short nLen =0;
//bKey1.if( nKeyOffset1)
nLen = (nKeyLen1 > nKeyLen2)?nKeyLen2:nKeyLen1;
for( short i = 0; i < nLen; i ++){
bXorKey[i+nXorKeyOffset] =(byte)( bKey1[i + nKeyOffset1] ^ bKey2[i+nKeyOffset2]);
}
return nLen;
}

/////该函数未检测过。代测试
/**
* @author steven
* @param bKey --用于计算的密钥的数组
* @param nkeyOffset-用于计算的密钥的偏移量
* @param nKeyLen - 用于计算的密钥的长度
* @param Init -用于计算的初始值
* @param bData -用于计算MAC的数据
* @param nLen-用于计算MAC的数据长度
* @param nNeedPad-是否需要进行补位
*/
/*
public short SingleDes_3Des_Mac_New(byte[] bKey ,short nKeyOffset,short nKeyLen, byte[] Init,byte[] bData ,short nLen,boolean nNeedPad,byte[] bMac , short MacOffset)
{
short nCount,i;
nCount = nLen;
if(nLen % 8 !=0){
nCount = (short)((nCount +8)/8 *8);
}
else if( nNeedPad )
nCount +=8;

byte[] bRes =JCSystem.makeTransientByteArray(nCount, JCSystem.CLEAR_ON_DESELECT); //???
byte[] bIn = JCSystem.makeTransientByteArray(nCount, JCSystem.CLEAR_ON_DESELECT); //????
Util.arrayCopyNonAtomic(bData, (short)0, bIn, (short)0, nLen);
if( nNeedPad)
bIn[nLen] = (byte)0x80;
if( nKeyLen == 8)
key =(DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES_TRANSIENT_DESELECT, KeyBuilder.LENGTH_DES, false);
else
key =(DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES_TRANSIENT_DESELECT, KeyBuilder.LENGTH_DES3_2KEY, false);
key.setKey(bKey, (short)nKeyOffset);

cp = Cipher.getInstance(Cipher.ALG_DES_CBC_NOPAD, false);
cp.init(key, Cipher.MODE_ENCRYPT, Init, (short)0, (short)8);
cp.doFinal(bIn, (short)0, nCount, bRes, (short)0);

Util.arrayCopyNonAtomic(bRes, (short)(nCount-8), bRes, (short)0, (short)8);
return bRes;
}
*/
public short SingDes_3Des_Mac_New(byte[] bKey ,short nKeyOffset,short nKeyLen, byte[] Init,byte[] bData ,short DataOffset,short nLen,boolean nNeedPad,byte[] bMac , short nMacOffset)
{
short

nCount,i;
if( bDebug ){
i = JCSystem.getAvailableMemory(JCSystem.CLEAR_ON_DESELECT);
nCount = JCSystem.getAvailableMemory(JCSystem.CLEAR_ON_RESET);
}
nCount = nLen;
if(nLen % 8 !=0){
nCount = (short)((nCount +8)/8 *8);
}
else if( nNeedPad )
nCount +=8;
byte[] bIn = new byte[nCount];
Util.arrayCopyNonAtomic(bData, (short)0, bIn, (short)0, nLen);
if( nNeedPad)
bIn[nLen] = (byte)0x80;
if( MyDebug.NewObject){
key =(DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES, false);
cp = Cipher.getInstance(Cipher.ALG_DES_CBC_ISO9797_M1, false);
}
key.setKey(bKey, (short)nKeyOffset);

for( i = 0; i < nCount /8 ; i ++){
if( i==0)
cp.init(key, Cipher.MODE_ENCRYPT,Init,(short)0,(short)8);
else
cp.init(key, Cipher.MODE_ENCRYPT,bRes,(short)0,(short)8);

cp.doFinal(bIn, (short)(i*8), (short)8, bRes, (short)0);
}
if( nKeyLen ==16){
key.setKey(bKey, (short)(8+nKeyOffset));
cp = Cipher.getInstance(Cipher.ALG_DES_CBC_ISO9797_M1, false);
cp.init(key, Cipher.MODE_DECRYPT);
cp.doFinal(bRes, (short)(0), (short)8, bRes, (short)0);


key.setKey(bKey, (short)nKeyOffset);
cp.init(key, Cipher.MODE_ENCRYPT);
cp.doFinal(bRes, (short)(0), (short)8, bRes, (short)0);

}
Util.arrayCopy(bRes, (short)0, bMac, nMacOffset, (short)8);
if( MyDebug.ObjectDel)
JCSystem.requestObjectDeletion();
return 8;
}
/**
* 参照PBOC1.0计算MAC(更新二进制,记录文件时,计算MAC值,首先使用离散子密钥的左8位对数据进行加密,
* 最后两步用离散子密钥的后8位对前面的结果进行解密,再用离散子密钥的左8位对数据进行加密
* @param bKey --加密数据使用的密钥(一般是离散子密钥)
* @param nKeyLen--密钥长度,8或者16
* @param Init --初始值,一般是4字节
* @param bData --要计算MAC的数据
* @param nLen -数据的长度
* @param nNeedPad --是否需要补位,一般需要强制补位的。
* @return
*/
public short SingDes_3Des_Mac(byte[] bKey ,short nKeyOffset,short nKeyLen, byte[] Init,byte[] bData ,short DataOffset,short nLen,boolean nNeedPad,byte[] bMac , short nMacOffset)
{
short nCount,i;
nCount = nLen;
//byte[] bTmp = new byte[16];
if(nLen % 8 !=0){
nCount = (short)((nCount +8)/8 *8);
}
else if( nNeedPad )
nCount +=8;
/*
byte[] bRes =new byte[8];
byte[] bIn = new byte[nCount];
Util.arrayCopyNonAtomic(bData, (short)0, bIn, (short)0, nLen);
if( nNeedPad)
bIn[nLen] = (byte)0x80;
*/
//key =(DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES, false);
//key.setKey(bKey, (short)nKeyOffset);
/*
Util.arrayFillNonAtomic(bTmp, (short)0, (short)16, (byte)0x00);
Util.arrayCopyNonAtomic(bKey, (short)0, bTmp, (short)0, (short)8);
Util.arrayCopyNonAtomic(bKey, (short)0, bTmp, (short)8, (short)8);
key.setKey(bTmp, (short)0)

;
*/
Util.arrayFillNonAtomic(bTmpKey, (short)0, (short)16, (byte)0x00);
Util.arrayFillNonAtomic(bRes, (short)0, (short)16, (byte)0x00);
//cp = Cipher.getInstance(Cipher.ALG_DES_CBC_ISO9797_M1, false);
Util.arrayCopy(bKey, nKeyOffset, bTmpKey, (short)0, (short)8);
Util.arrayCopy(bKey, nKeyOffset, bTmpKey, (short)8, (short)8);
if( MyDebug.NewObject){
key =(DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES, false);
cp = Cipher.getInstance(Cipher.ALG_DES_CBC_ISO9797_M1, false);
}
key.setKey(bTmpKey, (short)0);
//cp.init(key, Cipher.MODE_ENCRYPT)
for( i = 0; i < nCount /8 ; i ++){
if( i==0)
cp.init(key, Cipher.MODE_ENCRYPT,Init,(short)0,(short)8);
else
cp.init(key, Cipher.MODE_ENCRYPT,bRes,(short)0,(short)8);
//cp.doFinal(bIn, (short)(i*8), (short)8, bRes, (short)0);
Util.arrayFillNonAtomic(bMidData, (short)0, (short)8, (byte)0x00);
if( nNeedPad){ //如果需要补位,
if( nLen % 8 ==0){ //当输入的长度正好是8的倍数,则最后参与计算的数据,只有0x80
if( i == nCount/8 -1){
bMidData[0] =(byte)0x80;
}
else{
Util.arrayCopy(bData, (short)(i*8+DataOffset), bMidData, (short)0, (short)8);
}
}
else{
if( i == nCount/8 -1){
Util.arrayCopy(bData, (short)(i*8+DataOffset), bMidData, (short)0, (short)(nLen - i *8));
bMidData[nLen - i *8] = (byte)0x80;
}
else{
Util.arrayCopy(bData, (short)(i*8+DataOffset), bMidData, (short)0, (short)8);
}
}
}
else{ //不需要补位
if( nLen % 8 == 0){
Util.arrayCopy(bData, (short)(i*8+DataOffset), bMidData, (short)0, (short)8);
}
else{
Util.arrayCopy(bData, (short)(i*8+DataOffset), bMidData, (short)0, (short)(nLen - i *8));
}
}
cp.doFinal(bMidData, (short)(0), (short)8, bRes, (short)0);
}

if( nKeyLen ==16){
//key.setKey( bKey , (short)(8+nKeyOffset));
Util.arrayFillNonAtomic(bTmpKey, (short)0, (short)16, (byte)0x00);
Util.arrayCopy(bKey, (short)(nKeyOffset+8), bTmpKey, (short)0, (short)8);
Util.arrayCopy(bKey, (short)(nKeyOffset+8), bTmpKey, (short)8, (short)8);
/*Util.arrayFillNonAtomic(bTmp, (short)0, (short)16, (byte)0x00);
Util.arrayCopyNonAtomic(bKey, (short)8, bTmp, (short)0, (short)8);
Util.arrayCopyNonAtomic(bKey, (short)8, bTmp, (short)8, (short)8);
key.setKey(bTmp, (short)0);
*/
//cp = Cipher.getInstance(Cipher.ALG_DES_CBC_ISO9797_M1, false);
key.setKey(bTmpKey, (short)0);
cp.init(key, Cipher.MODE_DECRYPT);
cp.doFinal(bRes, (short)(0), (short)8, bRes, (short)0);

//key.setKey( bKey , (short)nKeyOffset);
Util.arrayFillNonAtomic(bTmpKey, (short)0, (short)16, (byte)0x00);
Util.arrayCopy(bKey, (short)(nKeyOffset), bTmpKey, (short)0, (short)8);
Util.arrayCopy(bKey, (short)(nKeyOffset), bTmpKey, (short)8, (short)8);

/*
Util.arrayFillNonAtomic(bTmp, (short)0, (short)16, (byt

e)0x00);
Util.arrayCopyNonAtomic(bKey, (short)0, bTmp, (short)0, (short)8);
Util.arrayCopyNonAtomic(bKey, (short)0, bTmp, (short)8, (short)8);
key.setKey(bTmp, (short)0);
*/
//cp = Cipher.getInstance(Cipher.ALG_DES_ECB_ISO9797_M1, false);
key.setKey(bTmpKey, (short)0);
cp.init(key, Cipher.MODE_ENCRYPT);
cp.doFinal(bRes, (short)(0), (short)8, bRes, (short)0);

}
Util.arrayCopy(bRes, (short)0, bMac, nMacOffset, (short)8);
if( MyDebug.ObjectDel)
JCSystem.requestObjectDeletion();
return (short)8;
}
public short SingDes_3Des_Mac(byte[] bKey , short nKeyLen, byte[] Init,byte[] bData ,short nLen,boolean nNeedPad,byte[] bMac , short nMacOffset)
{
/*
short nCount,i;
nCount = nLen;
//byte[] bTmp = new byte[16];
if(nLen % 8 !=0){
nCount = (short)((nCount +8)/8 *8);
}
else if( nNeedPad )
nCount +=8;

byte[] bRes =new byte[8];
byte[] bIn = new byte[nCount];
Util.arrayCopyNonAtomic(bData, (short)0, bIn, (short)0, nLen);
if( nNeedPad)
bIn[nLen] = (byte)0x80;
key =(DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES, false);
key.setKey(bKey, (short)0);

//Util.arrayFillNonAtomic(bTmp, (short)0, (short)16, (byte)0x00);
//Util.arrayCopyNonAtomic(bKey, (short)0, bTmp, (short)0, (short)8);
//Util.arrayCopyNonAtomic(bKey, (short)0, bTmp, (short)8, (short)8);
//key.setKey(bTmp, (short)0);
cp = Cipher.getInstance(Cipher.ALG_DES_CBC_ISO9797_M1, false);
for( i = 0; i < nCount /8 ; i ++){
if( i==0)
cp.init(key, Cipher.MODE_ENCRYPT,Init,(short)0,(short)8);
else
cp.init(key, Cipher.MODE_ENCRYPT,bRes,(short)0,(short)8);
cp.doFinal(bIn, (short)(i*8), (short)8, bRes, (short)0);
}

if( nKeyLen ==16){
key.setKey( bKey , (short)(8));
//Util.arrayFillNonAtomic(bTmp, (short)0, (short)16, (byte)0x00);
//Util.arrayCopyNonAtomic(bKey, (short)8, bTmp, (short)0, (short)8);
//Util.arrayCopyNonAtomic(bKey, (short)8, bTmp, (short)8, (short)8);
//key.setKey(bTmp, (short)0);

cp = Cipher.getInstance(Cipher.ALG_DES_CBC_ISO9797_M1, false);
cp.init(key, Cipher.MODE_DECRYPT);
cp.doFinal(bRes, (short)(0), (short)8, bRes, (short)0);

key.setKey( bKey , (short)0);

//Util.arrayFillNonAtomic(bTmp, (short)0, (short)16, (byte)0x00);
//Util.arrayCopyNonAtomic(bKey, (short)0, bTmp, (short)0, (short)8);
//Util.arrayCopyNonAtomic(bKey, (short)0, bTmp, (short)8, (short)8);
//key.setKey(bTmp, (short)0);

cp = Cipher.getInstance(Cipher.ALG_DES_CBC_ISO9797_M1, false);
cp.init(key, Cipher.MODE_ENCRYPT);
cp.doFinal(bRes, (short)(0), (short)8, bRes, (short)0);

}
return bRes;
*/
return SingDes_3Des_Mac(bKey,(short)0,nKeyLen,Init,bData,(short)0,nLen,nNeedPad, bMac , nMacOffset);
}
}

相关主题
相关文档
最新文档