java基于des3的加密解密
程序员文章站
2024-03-14 14:55:28
...
[size=medium] 年末,项目没那么紧了,能收钱的都已经收了,收不了的也没戏了,so,悠闲的日子又来了。闲的蛋疼,于是就研究了下公司某个证书,看看是否能**,于是乎,就出来了这篇东西。话不多扯,直接上主菜:[/size]
public class Test {
private DES3_CBC_CTX_2 _ctx = new DES3_CBC_CTX_2();
private final static long[][] Spbox = {
{0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
0x00010004L, 0x01004004L, 0x01000004L, 0x00010004L,
0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
0x01010400L, 0x01000400L, 0x01000000L, 0x00000400L,
0x01010004L, 0x00010000L, 0x00010400L, 0x01000804L,
0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L},
{0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
0x80001000L, 0x00008000L, 0x00108020L, 0x80100000L,
0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L},
{0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L},
{0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
0x00000081L, 0x00000000L, 0x00002000L, 0x00802000L,
0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L},
{0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
0x00080000L, 0x02000100L, 0x40000000L, 0x02080000L,
0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
0x40080100L, 0x00000100L, 0x02000800L, 0x42080000L,
0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L},
{0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L},
{0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
0x04000002L, 0x04010800L, 0x00000800L, 0x00200002L},
{0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
0x10041000L, 0x00041040L, 0x00001000L, 0x00800040L,
0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
0x00002000L, 0x10041040L, 0x00040040L, 0x10000040L,
0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L}
};
private static final long[][] keysD = {
{ 1060312887L, 1061105191L, 1044324135L, 1060972330L, 1061101340L, 925840175L, 792673310L, 1061104411L, 925842479L, 1061108237L, 1061106959L, 1027417653L, 1059006254L, 926889223L, 792669726L, 1061106751L, 1060974120L, 1061108539L, 1061108795L, 792401721L, 1061107498L, 1061031740L, 993736253L, 1061094702L, 1060978460L, 994000168L, 1061040669L, 792674075L, 1061108535L, 1044261913L, 926882085L, 524226367L },
{ 1058479411L, 1061095982L, 658445333L, 1061105437L, 1061108246L, 926628648L, 1061108284L, 1059915563L, 910106408L, 1059005758L, 524236071L, 524227898L, 1027023145L, 1060051769L, 1044331577L, 1043807028L, 1060713992L, 1061109007L, 993994014L, 1059989292L, 1044327983L, 792658725L, 1060977706L, 523972147L, 960437564L, 1061106203L, 1061105413L, 1058485018L, 524228877L, 1060839206L, 992941871L, 1060973577L },
{ 792080191L, 1061103884L, 1061100860L, 1060969759L, 926891567L, 926628410L, 792672573L, 1060975413L, 992945446L, 926887739L, 792534575L, 1027552559L, 1057963802L, 792667965L, 1061106238L, 1027480335L, 1060975931L, 524238622L, 977223465L, 792660031L, 1060977983L, 1059985186L, 1060842252L, 792674110L, 926891573L, 993928987L, 1060773690L, 1060978217L, 1061107231L, 842993463L, 926881555L, 1057960766L }
};
private static final long[][] keysE = {
{ 926881555L, 1057960766L, 1061107231L, 842993463L, 1060773690L, 1060978217L, 926891573L, 993928987L, 1060842252L, 792674110L, 1060977983L, 1059985186L, 977223465L, 792660031L, 1060975931L, 524238622L, 1061106238L, 1027480335L, 1057963802L, 792667965L, 792534575L, 1027552559L, 992945446L, 926887739L, 792672573L, 1060975413L, 926891567L, 926628410L, 1061100860L, 1060969759L, 792080191L, 1061103884L },
{ 992941871L, 1060973577L, 524228877L, 1060839206L, 1061105413L, 1058485018L, 960437564L, 1061106203L, 1060977706L, 523972147L, 1044327983L, 792658725L, 993994014L, 1059989292L, 1060713992L, 1061109007L, 1044331577L, 1043807028L, 1027023145L, 1060051769L, 524236071L, 524227898L, 910106408L, 1059005758L, 1061108284L, 1059915563L, 1061108246L, 926628648L, 658445333L, 1061105437L, 1058479411L, 1061095982L },
{ 926882085L, 524226367L, 1061108535L, 1044261913L, 1061040669L, 792674075L, 1060978460L, 994000168L, 993736253L, 1061094702L, 1061107498L, 1061031740L, 1061108795L, 792401721L, 1060974120L, 1061108539L, 792669726L, 1061106751L, 1059006254L, 926889223L, 1061106959L, 1027417653L, 925842479L, 1061108237L, 792673310L, 1061104411L, 1061101340L, 925840175L, 1044324135L, 1060972330L, 1060312887L, 1061105191L }
};
private long F(long l, long r, long[]key, int keyStart)
{
long work = ((r >> 4) | ((r << 28)&0xFFFFFFFFL)) ^ key[keyStart];
l ^= Spbox[6][(int)(work & 0x3f)];
l ^= Spbox[4][(int)((work >> 8) & 0x3f)];
l ^= Spbox[2][(int)((work >> 16) & 0x3f)];
l ^= Spbox[0][(int)((work >> 24) & 0x3f)];
work = r ^ key[keyStart+1];
l ^= Spbox[7][(int)(work & 0x3f)];
l ^= Spbox[5][(int)((work >> 8) & 0x3f)];
l ^= Spbox[3][(int)((work >> 16) & 0x3f)];
l ^= Spbox[1][(int)((work >> 24) & 0x3f)];
return l;
}
private static void cookey(long[] subkeys, long[] kn, int encrypt){
long[] raw;
int increment;
int i;
raw = kn;
int cookIndex = encrypt!=0 ? 0 : 30;
increment = encrypt!=0 ? 1 : -3;
for (i = 0; i < 16; i++) {
subkeys[cookIndex] = ( (raw[i] & 0x00fc0000L) << 6)&0xFFFFFFFFL;
subkeys[cookIndex] |= ( (raw[i] & 0x00000fc0L) << 10)&0xFFFFFFFFL;
subkeys[cookIndex] |= (raw[i+1] & 0x00fc0000L) >> 10;
subkeys[cookIndex++] |= (raw[i+1] & 0x00000fc0L) >> 6;
subkeys[cookIndex] = ( (raw[i] & 0x0003f000L) << 12)&0xFFFFFFFFL;
subkeys[cookIndex] |= ( (raw[i] & 0x0000003fL) << 16)&0xFFFFFFFFL;
subkeys[cookIndex] |= (raw[i+1] & 0x0003f000L) >> 4;
subkeys[cookIndex] |= (raw[i+1] & 0x0000003fL);
cookIndex += increment;
}
}
public void DES3_CBCInit(int type)
{
int encrypt = type;
this._ctx.iv[0] = 4208289545L;
_ctx.iv[1] = 1326297792L;
_ctx.originalIV[0] = 4208289545L;
_ctx.originalIV[1] = 1326297792L;
_ctx.encrypt = encrypt;
_ctx.subkeys = keysD;
if(encrypt == 1) //如果是加密
_ctx.subkeys = keysE;
else //如果是解密
_ctx.subkeys = keysD;
}
private void scrunch(long[] into, char[] outof, int outofStart){
int i = outofStart;
into[0] = ( (outof[i++] & 0xffL) << 24)&0xFFFFFFFFL;
into[0] |= ( ( (outof[i++] & 0xffL) << 16)&0xFFFFFFFFL);
into[0] |= ( ( (outof[i++] & 0xffL) << 8)&0xFFFFFFFFL);
into[0] |= (outof[i++] & 0xffL);
into[1] = ( (outof[i++] & 0xffL) << 24)&0xFFFFFFFFL;
into[1] |= ( ( (outof[i++] & 0xffL) << 16)&0xFFFFFFFFL);
into[1] |= ( ( (outof[i++] & 0xffL) << 8)&0xFFFFFFFFL);
into[1] |= (outof[i] & 0xffL);
}
private void unscrunch(char[] into,int intoStart, long[] outof){
int i=intoStart;
into[i++] = (char)((outof[0] >> 24) & 0xffL);
into[i++] = (char)((outof[0] >> 16) & 0xffL);
into[i++] = (char)((outof[0] >> 8) & 0xffL);
into[i++] = (char)( outof[0] & 0xffL);
into[i++] = (char)((outof[1] >> 24) & 0xffL);
into[i++] = (char)((outof[1] >> 16) & 0xffL);
into[i++] = (char)((outof[1] >> 8) & 0xffL);
into[i] = (char)( outof[1] & 0xffL);
}
public byte[] DES3_CBCUpdate(byte[] input)
{
int len = ((input.length+7)/8)*8;
long[] inputBlock=new long[2], work=new long[2];
if(len % 8 != 0) /* length check */
return new byte[0];
int nCount = len/8;
char[] chInput = new char[len];
for(int i=0; i< input.length; i++)
chInput[i] = (char)(0x0FF & input[i]);
char[][] chOutput = new char[nCount][8];
for(int i = 0; i < nCount; i++) {
scrunch(inputBlock, chInput,8*i);
/* Chain if encrypting. */
if(_ctx.encrypt == 0) {
work[0] = inputBlock[0];
work[1] = inputBlock[1];
}
else {
work[0] = inputBlock[0] ^ _ctx.iv[0];
work[1] = inputBlock[1] ^ _ctx.iv[1];
}
desfunc(work, _ctx.subkeys[0]);
desfunc(work, _ctx.subkeys[1]);
desfunc(work, _ctx.subkeys[2]);
/* Chain if decrypting, then update IV. */
if(_ctx.encrypt == 0) {
work[0] ^= _ctx.iv[0];
work[1] ^= _ctx.iv[1];
_ctx.iv[0] = inputBlock[0];
_ctx.iv[1] = inputBlock[1];
}
else {
_ctx.iv[0] = work[0];
_ctx.iv[1] = work[1];
}
unscrunch(chOutput[i],0, work);
}
int size = nCount*8;
byte[] output = new byte[size];
int index = 0;
for(int i=0; i< nCount; i++)
{
output[index++] = (byte)chOutput[i][0];
output[index++] = (byte)chOutput[i][1];
output[index++] = (byte)chOutput[i][2];
output[index++] = (byte)chOutput[i][3];
output[index++] = (byte)chOutput[i][4];
output[index++] = (byte)chOutput[i][5];
output[index++] = (byte)chOutput[i][6];
output[index++] = (byte)chOutput[i][7];
}
return output;
}
void desfunc(long[] block, long[] ks){
long left,right,work;
left = block[0];
right = block[1];
work = ((left >> 4) ^ right) & 0x0f0f0f0f;
right ^= work;
left ^= (work << 4)&0xFFFFFFFFL;
work = ((left >> 16) ^ right) & 0xffff;
right ^= work;
left ^= (work << 16)&0xFFFFFFFFL;
work = ((right >> 2) ^ left) & 0x33333333;
left ^= work;
right ^= (work << 2)&0xFFFFFFFFL;
work = ((right >> 8) ^ left) & 0xff00ff;
left ^= work;
right ^= (work << 8)&0xFFFFFFFFL;
right = ( (right << 1)&0xFFFFFFFFL) | (right >> 31);
work = (left ^ right) & 0xaaaaaaaa;
left ^= work;
right ^= work;
left = ( (left << 1)&0xFFFFFFFFL) | (left >> 31);
/* Now do the 16 rounds */
left = F(left,right,ks,0);
right = F(right,left,ks,2);
left = F(left,right,ks,4);
right = F(right,left,ks,6);
left = F(left,right,ks,8);
right = F(right,left,ks,10);
left = F(left,right,ks,12);
right = F(right,left,ks,14);
left = F(left,right,ks,16);
right = F(right,left,ks,18);
left = F(left,right,ks,20);
right = F(right,left,ks,22);
left = F(left,right,ks,24);
right = F(right,left,ks,26);
left = F(left,right,ks,28);
right = F(right,left,ks,30);
right = ((right << 31)&0xFFFFFFFFL) | (right >> 1);
work = (left ^ right) & 0xaaaaaaaa;
left ^= work;
right ^= work;
left = (left >> 1) | ((left << 31)&0xFFFFFFFFL);
work = ((left >> 8) ^ right) & 0xff00ff;
right ^= work;
left ^= (work << 8)&0xFFFFFFFFL;
work = ((left >> 2) ^ right) & 0x33333333;
right ^= work;
left ^= (work << 2)&0xFFFFFFFFL;
work = ((right >> 16) ^ left) & 0xffff;
left ^= work;
right ^= (work << 16)&0xFFFFFFFFL;
work = ((right >> 4) ^ left) & 0x0f0f0f0f;
left ^= work;
right ^= (work << 4)&0xFFFFFFFFL;
block[0] = right;
block[1] = left;
}
public static void main(String[] args)
{
String str = "adads343534/$90900";
Test des = new Test();
des.DES3_CBCInit(0);
byte[] result = des.DES3_CBCUpdate(str.getBytes());
des.DES3_CBCInit(1);
byte[] result2 = des.DES3_CBCUpdate(result);
System.out.println("====加密========"+new String(result));
System.out.println("====解密========"+new String(result2));
}
}
class DES3_CBC_CTX_2{
long[][] subkeys = new long[3][32];
long[] iv = new long[2];
long[] originalIV = new long [2];
int encrypt;
}