PB实现DES加解密

填充模式

加密操作前需要将明文分解成长度为8的块,若明文长度不是8的倍数则需要填充到8的倍数,以下是两张填充方式:
PKCS5:若数据需要填充n个字节才能对齐,则填充的每个字节值都是n;若数据已对齐,则填充一个长度为8的块,填充的每个字节值都是8
Zero:数据长度对齐时不填充,否则填充0

加密模式

ECB:电码本模式
CBC:密码分组链接模式
详细的加密流程参考 对称加密和分组加密中的四种模式(ECB、CBC、CFB、OFB)

ECB模式加解密操作

设置填充模式PKCS5,加密模式不用设置默认为ECB,秘钥DESPACS5,加密文本:PB实现DES/ECB模式加解密
在这里插入图片描述
十六进制密文为:D256468E014B4313BBF2E07E5BBDA9F8E9C6CDF1021AD55AA4C15B702FBAF205
base64密文为:0lZGjgFLQxO78uB+W72p+OnGzfECGtVapMFbcC+68gU=

解密上一步得到的十六进制密文
在这里插入图片描述
解密得到的明文为:PB实现DES/ECB模式加解密

CBC模式加解密操作

设置填充模式PKCS5,加密模式CBC,秘钥DESPACS5,初始化向量INITVECT,加密文本:PB实现DES/CBC模式加解密
在这里插入图片描述
十六进制密文为:DDB06F50F8A3B23105B5B1A0FABEA2ACA93A6C785AF25C79DADC93AE7457BB86
base64密文为:3bBvUPijsjEFtbGg+r6irKk6bHha8lx52tyTrnRXu4Y=

解密上一步得到的base64密文
在这里插入图片描述
解密得到的明文为:PB实现DES/CBC模式加解密

源代码

几个依赖项、demo中使用到的类源代码:
n_func_blob
n_func_radix
n_base64

发现BUG请留言或私信,以便修正(QQ:768310524 TEL:18649713925)
代码拷贝到文本编辑器,另存为 n_des.sru

$PBExportHeader$n_des.sru
forward
global type n_des from nonvisualobject
end type
type stbl from structure within n_des
end type
type sbox from structure within n_des
end type
end forward

type stbl from structure
	string		s_list[]
end type

type sbox from structure
	stbl		s_table[]
end type

global type n_des from nonvisualobject autoinstantiate
end type

type variables
public:
	CONSTANT STRING PKCS5 = 'PKCS5Padding'
	CONSTANT STRING Zero = 'ZeroPadding'
	
	CONSTANT STRING ECB = 'ECB'
	CONSTANT STRING CBC = 'CBC'

private:
	string padding = PKCS5
	string mode = ECB

	byte PC_1[] = {57,49,41,33,25,17,9,&
						1,58,50,42,34,26,18,&
						10,2,59,51,43,35,27,&
						19,11,3,60,52,44,36,&
						63,55,47,39,31,23,15,&
						7,62,54,46,38,30,22,&
						14,6,61,53,45,37,29,&
						21,13,5,28,20,12,4}
	
	byte PC_2[] = { 14,17,11,24,1,5,&
						 3,28,15,6,21,10,&
						 23,19,12,4,26,8,&
						 16,7,27,20,13,2,&
						 41,52,31,37,47,55,&
						 30,40,51,45,33,48,&
						 44,49,39,56,34,53,&
						 46,42,50,36,29,32}
	
	byte Rn[] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1}
	
	byte IP[] = {58,50,42,34,26,18,10,2,&
					60,52,44,36,28,20,12,4,&
					62,54,46,38,30,22,14,6,&
					64,56,48,40,32,24,16,8,&
					57,49,41,33,25,17,9,1,&
					59,51,43,35,27,19,11,3,&
					61,53,45,37,29,21,13,5,&
					63,55,47,39,31,23,15,7}
	
	byte BIT_SELECTION[] = {32,1,2,3,4,5,&
										4,5,6,7,8,9,&
										8,9,10,11,12,13,&
										12,13,14,15,16,17,&
										16,17,18,19,20,21,&
										20,21,22,23,24,25,&
										24,25,26,27,28,29,&
										28,29,30,31,32,1}
									
	byte P[] = { 16,7,20,21,&
					29,12,28,17,&
					1,15,23,26,&
					5,18,31,10,&
					2,8,24,14,&
					32,27,3,9,&
					19,13,30,6,&
					22,11,4,25}
	
	byte IP_1[] = { 40,8,48,16,56,24,64,32,&
						39,7,47,15,55,23,63,31,&
						38,6,46,14,54,22,62,30,&
						37,5,45,13,53,21,61,29,&
						36,4,44,12,52,20,60,28,&
						35,3,43,11,51,19,59,27,&
						34,2,42,10,50,18,58,26,&
						33,1,41,9,49,17,57,25}
	
	string Kn[16]
	char iv[]
	
	SBOX S_BOX[]
	
	n_func_blob fblob

end variables

forward prototypes
public subroutine setkey (blob key)
public subroutine setiv (blob ivector)
private subroutine calc_keys (blob key)
public subroutine setmode (string m)
public subroutine setpadding (string pd)
public function blob encode (blob buf)
public function blob decode (blob cypher)
private subroutine calc_blocks (string blocks[], boolean flag, ref string result[])
private function string calc_block (string block, boolean flag)
private function string fun (string r, string k)
end prototypes

public subroutine setkey (blob key);long length

length = len(key)
if length > 8 then
	key = blobmid(key , 1 , 8)
elseif length < 8 then
	key += fblob.fill(0 , 8 - length)
end if

calc_keys(key)
end subroutine

public subroutine setiv (blob ivector);long length

length = len(ivector)
if length > 8 then
	ivector = blobmid(ivector , 1 , 8)
elseif length < 8 then
	ivector += fblob.fill(0 , 8 - length)
end if

iv = fblob.Blob2Bin(ivector)
end subroutine

private subroutine calc_keys (blob key);char key_bit[]
char kn_bit[]
string c,d
char cd[]
char k_bit[]
int i,j
string k

key_bit = fblob.Blob2Bin(key)
for i = 1 to 56
	kn_bit[i] = key_bit[PC_1[i]]
next

k = string(kn_bit)
c = left(k,28)
d = right(k,28)

for i = 1 to 16
	c = mid(c,Rn[i] + 1) + left(c,Rn[i])
	d = mid(d,Rn[i] + 1) + left(d,Rn[i])
	cd = c + d
	for j = 1 to 48
		k_bit[j] = cd[PC_2[j]]
	next
	Kn[i] = k_bit
next

end subroutine

public subroutine setmode (string m);mode = m
end subroutine

public subroutine setpadding (string pd);padding = pd
end subroutine

public function blob encode (blob buf);blob rblob
int li_padding,li_value
char pchar[],hchar[],vchar[]
long i,j
long ll_len,ll_loop,ll_point
blob blockblob[]
string block[],cypher[],cypherhex[]
byte lbyte[],rbyte[]
string result

if upperbound(Kn) <= 0 then return rblob
if len(buf) <= 0 then return rblob

lbyte = GetByteArray(buf)
choose case padding
	case PKCS5
		li_padding = 8 - mod(len(buf),8)
		li_value = li_padding
	case Zero
		li_padding = 8 - mod(len(buf),8)
		if li_padding = 8 then li_padding = 0
		li_value = 0
	case else
		return rblob
end choose

ll_len = upperbound(lbyte)
for i = 1 to li_padding
	lbyte[ll_len + i] = li_value
next

ll_loop = fblob.slice(blob(lbyte) , 8 , blockblob)
for i = 1 to ll_loop
	block[i] = fblob.Blob2Bin(blockblob[i])
next

calc_blocks(block , true , cypher)

for i = 1 to ll_loop
	pchar = cypher[i]
	ll_point = 1
	for j = 1 to 8
		rbyte[8 * i - 8 + j] = byte(pchar[ll_point]) * 128 +&
									 byte(pchar[ll_point + 1]) * 64 +&
									 byte(pchar[ll_point + 2]) * 32 +&
									 byte(pchar[ll_point + 3]) * 16 +&
									 byte(pchar[ll_point + 4]) * 8 +&
									 byte(pchar[ll_point + 5]) * 4 +&
									 byte(pchar[ll_point + 6]) * 2 +&
									 byte(pchar[ll_point + 7])
		ll_point += 8
	next
next

return blob(rbyte)
end function

public function blob decode (blob cypher);blob lblb
long ll_len,ll_loop,ll_point
long i,j
char bchar[]
blob blockblob[]
string block[],result[]
byte lbyte[]
int li_padding

ll_len = len(cypher)
if ll_len <= 0 then return lblb
if mod(ll_len,8) <> 0 then return lblb

ll_loop = fblob.slice(cypher , 8 , blockblob)
for i = 1 to ll_loop
	block[i] = fblob.Blob2Bin(blockblob[i])
next

calc_blocks(block,false,result)

for i = 1 to ll_loop
	bchar = result[i]
	ll_point = 1
	for j = 1 to 8
		lbyte[8 * i - 8 + j] = byte(bchar[ll_point]) * 128 +&
									 byte(bchar[ll_point + 1]) * 64 +&
									 byte(bchar[ll_point + 2]) * 32 +&
									 byte(bchar[ll_point + 3]) * 16 +&
									 byte(bchar[ll_point + 4]) * 8 +&
									 byte(bchar[ll_point + 5]) * 4 +&
									 byte(bchar[ll_point + 6]) * 2 +&
									 byte(bchar[ll_point + 7]) 
		ll_point += 8
	next
next

choose case padding
	case PKCS5
		li_padding = lbyte[upperbound(lbyte)]
	case Zero
		
	case else
		return lblb
end choose

lblb = blob(lbyte)
return blobmid(lblb,1,len(lblb) - li_padding)
end function

private subroutine calc_blocks (string blocks[], boolean flag, ref string result[]);int i,j
long ll_loop
char vchar[],pchar[]

ll_loop = upperbound(blocks)
choose case mode
	case ECB
		for i = 1 to ll_loop
			result[i] = calc_block(blocks[i] , flag)
		next
	case CBC
		vchar = iv
		if flag then
			for i = 1 to ll_loop
				pchar = blocks[i]
				for j = 1 to 64
					if pchar[j] = vchar[j] then
						pchar[j] = '0'
					else
						pchar[j] = '1'
					end if
				next
				result[i] = calc_block(pchar , flag)
				vchar = result[i]
			next
		else
			for i = 1 to ll_loop
				pchar = calc_block(blocks[i] , flag)
				for j = 1 to 64
					if pchar[j] = vchar[j] then
						pchar[j] = '0'
					else
						pchar[j] = '1'
					end if
				next
				result[i] = pchar
				vchar = blocks[i]
			next
		end if
	case else
		
end choose

end subroutine

private function string calc_block (string block, boolean flag);
char pchar[],vtempchar[],result[]
char lnchar[],rnchar[],ltempchar[],rtempchar[]
string vstr
int i,j
string l,r,k

pchar = block
for i = 1 to 64
	vtempchar[i] = pchar[IP[i]]
next

vstr = vtempchar
lnchar = left(vstr,32)
rnchar = right(vstr,32)
for i = 1 to 16
	ltempchar = lnchar
	lnchar = rnchar
	if flag then
		k = Kn[i]
	else
		k = Kn[17 - i]
	end if
	rtempchar = fun(rnchar,k)
	for j = 1 to 32
		if ltempchar[j] = rtempchar[j] then
			rnchar[j] = '0'
		else
			rnchar[j] = '1'
		end if
	next
next

vtempchar = string(rnchar) + string(lnchar)
for i = 1 to 64
	result[i] = vtempchar[IP_1[i]]
next

return result
end function

private function string fun (string r, string k);char rchar[],echar[],kchar[],bchar[],schar[],result[]
string stemp
int i
byte row,col,vtemp

rchar = r
kchar = k
for i = 1 to 48
	echar[i] = rchar[BIT_SELECTION[i]]
	if echar[i] = kchar[i] then
		bchar[i] = '0'
	else
		bchar[i] = '1'
	end if
next

for i = 1 to 8
	vtemp = 6 * i - 5
	row = byte(bchar[vtemp]) * 2 + byte(bchar[vtemp + 5]) + 1
	col = byte(bchar[vtemp + 1]) * 8 + byte(bchar[vtemp + 2]) * 4 + byte(bchar[vtemp + 3]) * 2 + byte(bchar[vtemp + 4]) + 1
	stemp += S_BOX[i].S_TABLE[row].S_LIST[col]
next

schar = stemp
for i = 1 to 32
	result[i] = schar[P[i]]
next

return result
end function

on n_des.create
call super::create
TriggerEvent( this, "constructor" )
end on

on n_des.destroy
TriggerEvent( this, "destructor" )
call super::destroy
end on

event constructor;
S_BOX[1].S_TABLE[1].S_LIST = {'1110','0100','1101','0001','0010','1111','1011','1000','0011','1010','0110','1100','0101','1001','0000','0111'}
S_BOX[1].S_TABLE[2].S_LIST = {'0000','1111','0111','0100','1110','0010','1101','0001','1010','0110','1100','1011','1001','0101','0011','1000'}
S_BOX[1].S_TABLE[3].S_LIST = {'0100','0001','1110','1000','1101','0110','0010','1011','1111','1100','1001','0111','0011','1010','0101','0000'}
S_BOX[1].S_TABLE[4].S_LIST = {'1111','1100','1000','0010','0100','1001','0001','0111','0101','1011','0011','1110','1010','0000','0110','1101'}

S_BOX[2].S_TABLE[1].S_LIST = {'1111','0001','1000','1110','0110','1011','0011','0100','1001','0111','0010','1101','1100','0000','0101','1010'}
S_BOX[2].S_TABLE[2].S_LIST = {'0011','1101','0100','0111','1111','0010','1000','1110','1100','0000','0001','1010','0110','1001','1011','0101'}
S_BOX[2].S_TABLE[3].S_LIST = {'0000','1110','0111','1011','1010','0100','1101','0001','0101','1000','1100','0110','1001','0011','0010','1111'}
S_BOX[2].S_TABLE[4].S_LIST = {'1101','1000','1010','0001','0011','1111','0100','0010','1011','0110','0111','1100','0000','0101','1110','1001'}

S_BOX[3].S_TABLE[1].S_LIST = {'1010','0000','1001','1110','0110','0011','1111','0101','0001','1101','1100','0111','1011','0100','0010','1000'}
S_BOX[3].S_TABLE[2].S_LIST = {'1101','0111','0000','1001','0011','0100','0110','1010','0010','1000','0101','1110','1100','1011','1111','0001'}
S_BOX[3].S_TABLE[3].S_LIST = {'1101','0110','0100','1001','1000','1111','0011','0000','1011','0001','0010','1100','0101','1010','1110','0111'}
S_BOX[3].S_TABLE[4].S_LIST = {'0001','1010','1101','0000','0110','1001','1000','0111','0100','1111','1110','0011','1011','0101','0010','1100'}

S_BOX[4].S_TABLE[1].S_LIST = {'0111','1101','1110','0011','0000','0110','1001','1010','0001','0010','1000','0101','1011','1100','0100','1111'}
S_BOX[4].S_TABLE[2].S_LIST = {'1101','1000','1011','0101','0110','1111','0000','0011','0100','0111','0010','1100','0001','1010','1110','1001'}
S_BOX[4].S_TABLE[3].S_LIST = {'1010','0110','1001','0000','1100','1011','0111','1101','1111','0001','0011','1110','0101','0010','1000','0100'}
S_BOX[4].S_TABLE[4].S_LIST = {'0011','1111','0000','0110','1010','0001','1101','1000','1001','0100','0101','1011','1100','0111','0010','1110'}

S_BOX[5].S_TABLE[1].S_LIST = {'0010','1100','0100','0001','0111','1010','1011','0110','1000','0101','0011','1111','1101','0000','1110','1001'}
S_BOX[5].S_TABLE[2].S_LIST = {'1110','1011','0010','1100','0100','0111','1101','0001','0101','0000','1111','1010','0011','1001','1000','0110'}
S_BOX[5].S_TABLE[3].S_LIST = {'0100','0010','0001','1011','1010','1101','0111','1000','1111','1001','1100','0101','0110','0011','0000','1110'}
S_BOX[5].S_TABLE[4].S_LIST = {'1011','1000','1100','0111','0001','1110','0010','1101','0110','1111','0000','1001','1010','0100','0101','0011'}

S_BOX[6].S_TABLE[1].S_LIST = {'1100','0001','1010','1111','1001','0010','0110','1000','0000','1101','0011','0100','1110','0111','0101','1011'}
S_BOX[6].S_TABLE[2].S_LIST = {'1010','1111','0100','0010','0111','1100','1001','0101','0110','0001','1101','1110','0000','1011','0011','1000'}
S_BOX[6].S_TABLE[3].S_LIST = {'1001','1110','1111','0101','0010','1000','1100','0011','0111','0000','0100','1010','0001','1101','1011','0110'}
S_BOX[6].S_TABLE[4].S_LIST = {'0100','0011','0010','1100','1001','0101','1111','1010','1011','1110','0001','0111','0110','0000','1000','1101'}

S_BOX[7].S_TABLE[1].S_LIST = {'0100','1011','0010','1110','1111','0000','1000','1101','0011','1100','1001','0111','0101','1010','0110','0001'}
S_BOX[7].S_TABLE[2].S_LIST = {'1101','0000','1011','0111','0100','1001','0001','1010','1110','0011','0101','1100','0010','1111','1000','0110'}
S_BOX[7].S_TABLE[3].S_LIST = {'0001','0100','1011','1101','1100','0011','0111','1110','1010','1111','0110','1000','0000','0101','1001','0010'}
S_BOX[7].S_TABLE[4].S_LIST = {'0110','1011','1101','1000','0001','0100','1010','0111','1001','0101','0000','1111','1110','0010','0011','1100'}

S_BOX[8].S_TABLE[1].S_LIST = {'1101','0010','1000','0100','0110','1111','1011','0001','1010','1001','0011','1110','0101','0000','1100','0111'}
S_BOX[8].S_TABLE[2].S_LIST = {'0001','1111','1101','1000','1010','0011','0111','0100','1100','0101','0110','1011','0000','1110','1001','0010'}
S_BOX[8].S_TABLE[3].S_LIST = {'0111','1011','0100','0001','1001','1100','1110','0010','0000','0110','1010','1101','1111','0011','0101','1000'}
S_BOX[8].S_TABLE[4].S_LIST = {'0010','0001','1110','0111','0100','1010','1000','1101','1111','1100','1001','0000','0011','0101','0110','1011'}



end event


  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值