[ GORSHTAK @ 08.06.2013. 01:08 ] @
Zdravo, cilj mi je da u C-u uradim MAC CBC, i treba mi pomoć oko razumevanja kako se to radi. Proučavao sam kod iz openssl-a, ali rezultat se ne podudara sa rezultatom dobijenim u javi Java kod koji radi: Code (java): public class MacCBC { private Mac mac = null; public MacCBC(){ BouncyCastleProvider prov = new BouncyCastleProvider(); Security.addProvider(prov); BlockCipher cipher = new DESedeEngine(); mac = new CBCBlockCipherMac(cipher); } public byte[] hashIt(byte data[], byte key[], byte iv[]) { KeyParameter keyP = new KeyParameter(key); ParametersWithIV param = new ParametersWithIV(keyP, iv); mac.init(param); mac.update(data, 0, data.length); byte out[] = new byte[4]; mac.doFinal(out, 0); return out; } } Kod iz openssl-a: Code (c): #define DES_LONG unsigned long #define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ *((c)++)=(unsigned char)(((l)>>24L)&0xff)) #define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ l|=((DES_LONG)(*((c)++)))<< 8L, \ l|=((DES_LONG)(*((c)++)))<<16L, \ l|=((DES_LONG)(*((c)++)))<<24L) #define c2ln(c,l1,l2,n) { c+=n; l1=l2=0; \ switch (n) { \ case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \ case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \ case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \ case 5: l2|=((DES_LONG)(*(--(c)))); \ case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \ case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \ case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \ case 1: l1|=((DES_LONG)(*(--(c)))); \ } \ } typedef unsigned char DES_cblock[8]; typedef /* const */ unsigned char const_DES_cblock[8]; typedef struct DES_ks { union { DES_cblock cblock; /* make sure things are correct size on machines with * 8 byte longs */ DES_LONG deslong[2]; } ks[16]; } DES_key_schedule; long DES_cbc_cksum(const unsigned char *in, DES_cblock *output, long length, DES_key_schedule *schedule, const_DES_cblock *ivec) { register long tout0,tout1,tin0,tin1; register long l=length; long tin[2]; unsigned char *out = &(*output)[0]; const unsigned char *iv = &(*ivec)[0]; c2l(iv,tout0); c2l(iv,tout1); for (; l>0; l-=8) { if (l >= 8) { c2l(in,tin0); c2l(in,tin1); } else c2ln(in,tin0,tin1,l); tin0^=tout0; tin[0]=tin0; tin1^=tout1; tin[1]=tin1; DES_encrypt1((long *)tin,schedule,DES_ENCRYPT); /////// OVDE????? /* fix 15/10/91 eay - thanks to [email protected] */ tout0=tin[0]; tout1=tin[1]; } if (out != NULL) { l2c(tout0,out); l2c(tout1,out); } tout0=tin0=tin1=tin[0]=tin[1]=0; /* Transform the data in tout1 so that it will match the return value that the MIT Kerberos mit_des_cbc_cksum API returns. */ tout1 = ((tout1 >> 24L) & 0x000000FF) | ((tout1 >> 8L) & 0x0000FF00) | ((tout1 << 8L) & 0x00FF0000) | ((tout1 << 24L) & 0xFF000000); return(tout1); } Dakle ono što sam do sad shvatio: - poruka se deli na po 8 bajta, delovi se obrađuju i kriptuju - pošto je krajnji rezultat 8 bajta, za rezultat se uzimaju poslednja 4 bajta Ono što ne znam je, da li umesto DES_encrypt1 (nisam siguran ni koji je to tačno algoritam) treba da stavim 3des cbc i da IV koji dobijem tokom obrade treba da iskoristim za sledeću obradu, tj. da ne resetujem na nulu. Ili je možda ovaj C kod potpuno pogrešan.... |