如何用C实现3DES算法..

Python018

如何用C实现3DES算法..,第1张

//功能:实现DES及3DES加解密的算法

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include "des.h"

//函数声明

int Do_DES(char* strSrc, char* strKey, char* strDest, char flag)

int Do_3DES(char* strSrc, char* strKey, char* strDest, char flag)

//主函数

int main(int argc, char** argv)

{

char src16[16+1],key16[16+1],key48[48+1],dest16[16+1]

if(argc != 3)

{

fprintf(stderr,"Usage: [%s -e|-d s|3]\n",argv[0])

exit(1)

}

if(strcmp(argv[2],"-s") == 0)

{

if(strcmp(argv[1],"-e") == 0)

{

fprintf(stderr,"Please input the string that you want to encrypt(16 hex number):\n")

memset(src16,0,sizeof(src16))

scanf("%s",src16)

fprintf(stderr,"Please input the Key string(16 hex number):\n")

memset(key16,0,sizeof(key16))

scanf("%s",key16)

memset(dest16,0,sizeof(dest16))

Do_DES(src16,key16,dest16,'e')

fprintf(stderr,"Result: [%s]\n",dest16)

}

else if(strcmp(argv[1],"-d") == 0)

{

fprintf(stderr,"Please input the string that you want to decrypt(16 hex number):\n")

memset(src16,0,sizeof(src16))

scanf("%s",src16)

fprintf(stderr,"Please input the Key string(16 hex number):\n")

memset(key16,0,sizeof(key16))

scanf("%s",key16)

memset(dest16,0,sizeof(dest16))

Do_DES(src16,key16,dest16,'d')

fprintf(stderr,"Result: [%s]\n",dest16)

}

else

return -1

}

else if(strcmp(argv[2],"-3") == 0)

{

if(strcmp(argv[1],"-e") == 0)

{

fprintf(stderr,"Please input the string that you want to encrypt(16 hex number):\n")

memset(src16,0,sizeof(src16))

scanf("%s",src16)

fprintf(stderr,"Please input the Key string(16 hex number):\n")

memset(key48,0,sizeof(key48))

scanf("%s",key48)

memset(dest16,0,sizeof(dest16))

Do_3DES(src16,key48,dest16,'e')

fprintf(stderr,"Result: [%s]\n",dest16)

}

else if(strcmp(argv[1],"-d") == 0)

{

fprintf(stderr,"Please input the string that you want to decrypt(16 hex number):\n")

memset(src16,0,sizeof(src16))

scanf("%s",src16)

fprintf(stderr,"Please input the Key string(16 hex number):\n")

memset(key48,0,sizeof(key48))

scanf("%s",key48)

memset(dest16,0,sizeof(dest16))

Do_3DES(src16,key48,dest16,'d')

fprintf(stderr,"Result: [%s]\n",dest16)

}

else

return -1

}

else

return -1

return 0

}

//做DES加密或解密运算

int Do_DES(char* strSrc, char* strKey, char* strDest, char flag)

{

int i,j

unsigned char subKey[16][48+1],byte8[8+1],bits[64+1],strTmp[64+1]

unsigned char L0[32+1],R0[32+1],Lx[32+1],Rx[32+1]

if(!( flag == 'e' || flag == 'E' || flag == 'd' || flag == 'D'))

return -1

if(strSrc == NULL || strKey == NULL)

return -2

if(flag == 'e' || flag == 'E')

{

memset(byte8,0,sizeof(byte8))

BCDToByte(strKey, 16, byte8)

memset(bits,0,sizeof(bits))

ByteToBit(byte8, 8, bits)

Des_GenSubKey(bits,subKey)

BCDToByte(strSrc, 16, byte8)

ByteToBit(byte8, 8, bits)

Des_IP(bits, strTmp)

memcpy(L0,strTmp,32)

memcpy(R0,strTmp+32,32)

for(i=0i<16i++)

{

memcpy(Lx,R0,32)

Des_F(R0,subKey[i],Rx)

Do_XOR(L0,32,Rx)

memcpy(L0,Lx,32)

memcpy(R0,Rx,32)

}

memcpy(bits,R0,32)

memcpy(bits+32,L0,32)

Des_IP_1(bits,strTmp)

BitToByte(strTmp,64,byte8)

ByteToBCD(byte8,8,strDest)

}

else

{

memset(byte8,0,sizeof(byte8))

BCDToByte(strKey, 16, byte8)

memset(bits,0,sizeof(bits))

ByteToBit(byte8, 8, bits)

Des_GenSubKey(bits,subKey)

BCDToByte(strSrc, 16, byte8)

ByteToBit(byte8, 8, bits)

Des_IP(bits, strTmp)

memcpy(L0,strTmp,32)

memcpy(R0,strTmp+32,32)

for(i=0i<16i++)

{

memcpy(Lx,R0,32)

Des_F(R0,subKey[15-i],Rx)

Do_XOR(L0,32,Rx)

memcpy(L0,Lx,32)

memcpy(R0,Rx,32)

}

memcpy(bits,R0,32)

memcpy(bits+32,L0,32)

Des_IP_1(bits,strTmp)

BitToByte(strTmp,64,byte8)

ByteToBCD(byte8,8,strDest)

}

return 0

}

//做3DES加密或解密运算

int Do_3DES(char* strSrc, char* strKey, char* strDest, char flag)

{

unsigned char strBCDKey[32+1],strByteKey[16+1]

unsigned char strMidDest1[16+1],strMidDest2[16+1]

unsigned char strLKey[16+1],strMKey[16+1],strRKey[16+1]

if(!( flag == 'e' || flag == 'E' || flag == 'd' || flag == 'D'))

return -1

if(strSrc == NULL || strKey == NULL)

return -2

if(strlen(strKey) <32)

return -3

if(flag == 'e' || flag == 'E')

{

memset(strBCDKey,0,sizeof(strBCDKey))

memcpy(strBCDKey,strKey,32)

memset(strLKey,0,sizeof(strLKey))

memcpy(strLKey,strBCDKey,16)

memset(strRKey,0,sizeof(strRKey))

memcpy(strRKey,strBCDKey+16,16)

Do_DES(strSrc,strLKey,strMidDest1,'e')

Do_DES(strMidDest1,strRKey,strMidDest2,'d')

Do_DES(strMidDest2,strLKey,strMidDest1,'e')

memcpy(strDest,strMidDest1,16)

}

else

{

memset(strBCDKey,0,sizeof(strBCDKey))

memcpy(strBCDKey,strKey,32)

memset(strLKey,0,sizeof(strLKey))

memcpy(strLKey,strBCDKey,16)

memset(strRKey,0,sizeof(strRKey))

memcpy(strRKey,strBCDKey+16,16)

Do_DES(strSrc,strLKey,strMidDest1,'d')

Do_DES(strMidDest1,strRKey,strMidDest2,'e')

Do_DES(strMidDest2,strLKey,strMidDest1,'d')

memcpy(strDest,strMidDest1,16)

}

return 0

}

// C 语言 DES用的是 ECB模式, 没有填充

// 因此Java端要对应, 你的明文是 liubiao 吗?

// 另外 DES已经不安全了, 如果可以改为 3DES或者 AES吧。

public class LearnDes {

public static void main(String[] args) {

try {

System.out.println(encrypt("liubiao", "12345678"))

System.out.println(decrypt("26d086be3a3a62fc", "12345678"))

} catch (Exception e) {

e.printStackTrace()

}

}

public static String encrypt(String message, String key) throws Exception {

//Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding")

Cipher cipher = Cipher.getInstance("DES/ECB/NOPADDING")

DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"))

SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES")

SecretKey secretKey = keyFactory.generateSecret(desKeySpec)

IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"))

//cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv)

cipher.init(Cipher.ENCRYPT_MODE, secretKey )

return toHexString(cipher.doFinal(message.getBytes("UTF-8")))

}

public static String decrypt(String message, String key) throws Exception {

byte[] bytesrc = convertHexString(message)

//Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding")

Cipher cipher = Cipher.getInstance("DES/ECB/NOPADDING")

DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"))

SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES")

SecretKey secretKey = keyFactory.generateSecret(desKeySpec)

IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"))

//cipher.init(Cipher.DECRYPT_MODE, secretKey, iv)

cipher.init(Cipher.DECRYPT_MODE, secretKey )

byte[] retByte = cipher.doFinal(bytesrc)

return new String(retByte)

}

public static byte[] convertHexString(String ss) {

byte digest[] = new byte[ss.length() / 2]

for (int i = 0i <digest.lengthi++) {

String byteString = ss.substring(2 * i, 2 * i + 2)

int byteValue = Integer.parseInt(byteString, 16)

digest[i] = (byte) byteValue

}

return digest

}

public static String toHexString(byte b[]) {

StringBuffer hexString = new StringBuffer()

for (int i = 0i <b.lengthi++) {

String plainText = Integer.toHexString(0xff &b[i])

if (plainText.length() <2)

plainText = "0" + plainText

hexString.append(plainText)

}

return hexString.toString()

}

}