PDA

View Full Version : BlowFish



Inprise
دوشنبه 01 دی 1382, 08:11 صبح
سلام

الگوریتم رمزنگاری متقارن BlowFish یکی از روشهای متداول رمزنگاری است . این الگوریتم با پذیرش کلید عمومی از 32 بیت تا 448 بیت ، جایگزین خوبی برای روشهائی مثل DES است . ( خصوصا در کشورهائی مثل آمریکا که صدور و فروش نرم افزارهای دارای سیستم رمزنگاری به خارج از کشور ممنوع و برای استفاده های داخلی هم در طول کلید محدودیتهائی وجود داره )

از این روش امروزه به وفور در نرم افزارهای گسترده و سازمانی استفاده میشه ، به عنوان مثال Oracle . این الگوریتم در سال 1993 توسط Bruce Schneier طراحی و توسعه داده شد .

توضیحات مفیدی برای این الگوریتم اینجا : http://www.schneier.com/blowfish.html است که میتونید استفاده کنید . پیاده سازی های متعددی از این الگوریتم به زبانهای سی ، سی شارپ ، جاوا ، دلفی ، بیسیک وجود داره که در صورت نیاز با یک جستجوی ساده میتونید پیداشون کنید .

سورس الگوریتم :

فایل هدر برای دسترسی به توابع :


#define MAXKEYBYTES 56 /* 448 bits */
// #define little_endian 1 /* Eg: Intel */
#define big_endian 1 /* Eg: Motorola */

short opensubkeyfile(void);
unsigned long F(unsigned long x);
void Blowfish_encipher(unsigned long *xl, unsigned long *xr);
void Blowfish_decipher(unsigned long *xl, unsigned long *xr);

متن الگوریتم و پیاده سازی توابع :


#ifdef little_endian /* Eg: Intel */
#include <dos.h>
#include <graphics.h>
#include <io.h>
#endif

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#ifdef little_endian /* Eg: Intel */
#include <alloc.h>
#endif

#include <ctype.h>

#ifdef little_endian /* Eg: Intel */
#include <dir.h>
#include <bios.h>
#endif

#ifdef big_endian
#include <Types.h>
#endif

#include "Blowfish.h"

#define N 16
#define noErr 0
#define DATAERROR -1
#define KEYBYTES 8
#define subkeyfilename "Blowfish.dat"

unsigned long P[N + 2];
unsigned long S[4][256];
FILE* SubkeyFile;

short opensubkeyfile(void) /* read only */
{
short error;

error = noErr;

if((SubkeyFile = fopen(subkeyfilename,"rb")) == NULL) {
error = DATAERROR;
}

return error;
}

unsigned long F(unsigned long x)
{
unsigned short a;
unsigned short b;
unsigned short c;
unsigned short d;
unsigned long y;

d = x & 0x00FF;
x >>= 8;
c = x & 0x00FF;
x >>= 8;
b = x & 0x00FF;
x >>= 8;
a = x & 0x00FF;
//y = ((S[0][a] + S[1][b]) ^ S[2][c]) + S[3][d];
y = S[0][a] + S[1][b];
y = y ^ S[2][c];
y = y + S[3][d];

return y;
}

void Blowfish_encipher(unsigned long *xl, unsigned long *xr)
{
unsigned long Xl;
unsigned long Xr;
unsigned long temp;
short i;

Xl = *xl;
Xr = *xr;

for (i = 0; i < N; ++i) {
Xl = Xl ^ P[i];
Xr = F(Xl) ^ Xr;

temp = Xl;
Xl = Xr;
Xr = temp;
}

temp = Xl;
Xl = Xr;
Xr = temp;

Xr = Xr ^ P[N];
Xl = Xl ^ P[N + 1];

*xl = Xl;
*xr = Xr;
}

void Blowfish_decipher(unsigned long *xl, unsigned long *xr)
{
unsigned long Xl;
unsigned long Xr;
unsigned long temp;
short i;

Xl = *xl;
Xr = *xr;

for (i = N + 1; i > 1; --i) {
Xl = Xl ^ P[i];
Xr = F(Xl) ^ Xr;

/* Exchange Xl and Xr */
temp = Xl;
Xl = Xr;
Xr = temp;
}

/* Exchange Xl and Xr */
temp = Xl;
Xl = Xr;
Xr = temp;

Xr = Xr ^ P[1];
Xl = Xl ^ P[0];

*xl = Xl;
*xr = Xr;
}

short InitializeBlowfish(char key[], short keybytes)
{
short i;
short j;
short k;
short error;
short numread;
unsigned long data;
unsigned long datal;
unsigned long datar;

/* First, open the file containing the array initialization data */
error = opensubkeyfile();
if (error == noErr) {
for (i = 0; i < N + 2; ++i) {
numread = fread(&data, 4, 1, SubkeyFile);
#ifdef little_endian /* Eg: Intel We want to process things in byte */
/* order, not as rearranged in a longword */
data = ((data & 0xFF000000) >> 24) |
((data & 0x00FF0000) >> 8) |
((data & 0x0000FF00) << 8) |
((data & 0x000000FF) << 24);
#endif

if (numread != 1) {
return DATAERROR;
} else {
P[i] = data;
}
}

for (i = 0; i < 4; ++i) {
for (j = 0; j < 256; ++j) {
numread = fread(&data, 4, 1, SubkeyFile);

#ifdef little_endian /* Eg: Intel We want to process things in byte */
/* order, not as rearranged in a longword */
data = ((data & 0xFF000000) >> 24) |
((data & 0x00FF0000) >> 8) |
((data & 0x0000FF00) << 8) |
((data & 0x000000FF) << 24);
#endif

if (numread != 1) {
return DATAERROR;
} else {
S[i][j] = data;
}
}
}

fclose(SubkeyFile);

j = 0;
for (i = 0; i < N + 2; ++i) {
data = 0x00000000;
for (k = 0; k < 4; ++k) {
data = (data << 8) | key[j];
j = j + 1;
if (j >= keybytes) {
j = 0;
}
}
P[i] = P[i] ^ data;
}

datal = 0x00000000;
datar = 0x00000000;

for (i = 0; i < N + 2; i += 2) {
Blowfish_encipher(&datal, &datar);

P[i] = datal;
P[i + 1] = datar;
}

for (i = 0; i < 4; ++i) {
for (j = 0; j < 256; j += 2) {

Blowfish_encipher(&datal, &datar);

S[i][j] = datal;
S[i][j + 1] = datar;
}
}
} else {
printf("Unable to open subkey initialization file : %d\n", error);
}

return error;
}

موفق باشید

Marine
چهارشنبه 04 آذر 1383, 02:52 صبح
میشه توضیحاتی در باره نحوه عملکرد این الگوریتم بدید ؟