8086实现RC4加密解密过程

8086实现RC4加密解密过程

对应题目

在这里插入图片描述
本代码为该题所写。

代码

DATA SEGMENT
KEY_LEN DB 1 DUP(0)
KEY DB 100 DUP(0)
TEXT_LEN DB 1 DUP(0)
PLAINTEXT DB 100 DUP(0)
CIPHERTEXT DB 100 DUP(0)

RETEXT_LEN DB 1 DUO(0)
RECIPHERTEXT DB 100 DUP(0)
REPLAINTEXT DB 100 DUP(0)

TIPS1 DB 'E','n','t','e','r',' ','t','h','e',' ','k','e','y',' ','a','n','d',' ','p','l','a','i','n','t','e','x','t',0DH,0AH,'$'
TIPS2 DB 'E','n','t','e','r',' ','t','h','e',' ','k','e','y',' ','a','n','d',' ','c','i','p','h','e','r','t','e','x','t',0DH,0AH,'$'

S DB 256 DUP(0)
K DB 256 DUP(0)
TEMP DB 1 DUP(0)
LIST DB 30H,31H,32H,33H,34H,35H,36H,37H,38H,39H,41H,42H,43H,44H,45H,46H

DATA ENDS


CODE SEGMENT
MAIN PROC FAR
ASSUME CS:CODE,DS:DATA;段分配
START:
MOV AX, DATA;段初始化
MOV DS, AX

CALL INPUT1

CALL INITIAL

CALL ENCIPHER

CALL OUTPUT_CIPHERTEXT

CALL INPUT2

CALL INITIAL

CALL DECIPHER

CALL OUTPUT_REPLAINTEXT

;DONTSTOP:
;JMP DONTSTOP

MOV AH, 4CH
INT 21H
                                                    

MAIN ENDP



INITIAL PROC NEAR
;/*初始化函数*/
;void rc4_init(unsigned char*s,unsigned char*key, unsigned long Len)
;{
;    int i=0,j=0;
;    unsigned char k[256]={0};
;    unsigned char tmp=0;
;    for(i=0;i<256;i++) {
;        s[i]=i;
;        k[i]=key[i%Len];
;    }
;    for(i=0;i<256;i++) {
;        j=(j+s[i]+k[i])%256;
;        tmp=s[i];
;        s[i]=s[j];//交换s[i]和s[j]
;        s[j]=tmp;
;    }
;}
;---------------------------------------------------------------------------------------------------------

MOV BX, 0;i
MOV DL, KEY_LEN
NEXT1:
MOV AL, BL
MOV AH, 0
MOV S[BX], AL;S初始化
DIV DL
MOV AL, AH
MOV AH, 0
MOV SI, AX
MOV DH, KEY[SI]
MOV K[BX], DH;K初始化
INC BX
CMP BX, 256
JB NEXT1

MOV BX, 0;i
MOV AX, 0;j
NEXT2:
MOV DH, 0
MOV DL, S[BX]
ADD AX, DX
MOV DL, K[BX] 
ADD AX, DX
MOV DX, 0
MOV SI, 256
DIV SI;计算J
MOV SI, DX
MOV AX, DX
MOV DL, S[BX];交换S[i]和S[j]
MOV TEMP, DL
MOV DL, S[SI]
MOV S[BX], DL
MOV DL, TEMP
MOV S[SI], DL
INC BX
CMP BX, 256
JB NEXT2

RET
    
INITIAL ENDP

;------------------------------------------------------------------------------------------------------------

ENCIPHER PROC NEAR
;/*加解密*/
;void rc4_crypt(unsigned char*s,unsigned char*Data,unsigned long Len)
;{
;    int i=0,j=0,t=0;
;    unsigned long k=0;
;    unsigned char tmp;
;    for(k=0;k<Len;k++)
;    {
;        i=(i+1)%256;
;        j=(j+s[i])%256;
;        tmp=s[i];
;        s[i]=s[j];//交换s[x]和s[y]
;        s[j]=tmp;
;        t=(s[i]+s[j])%256;
;        Data[k]^=s[t];
;    }
;}

MOV BX, 0;k
MOV SI, 0;i
MOV DI, 0;j
MOV CX, 256

NEXT3:
MOV AX, SI
INC AX
MOV DX, 0
DIV CX
MOV SI, DX
MOV AL, S[SI]
MOV AH, 0
ADD DI, AX
MOV AX, DI
MOV DX, 0
DIV CX
MOV DI, DX
MOV AL, S[SI]
MOV TEMP, AL
MOV AL, S[DI]
MOV S[SI], AL
MOV AL, TEMP
MOV S[DI], AL
MOV AL, S[SI]
ADD AL, S[DI]
JNC NEXT4
MOV AH, 1
JMP NEXT5
NEXT4:
MOV AH, 0
NEXT5:
MOV DX, 0
DIV CX
PUSH SI
MOV SI, DX
MOV AL, S[SI]
MOV AH, PLAINTEXT[BX]
XOR AH, AL
MOV CIPHERTEXT[BX], AH
POP SI
INC BX
CMP BL, TEXT_LEN
JB NEXT3
RET    
    
ENCIPHER ENDP

;---------------------------------------------------------------------------------------------------------------

INPUT1 PROC NEAR


MOV DX, OFFSET TIPS1
MOV AH, 09H
INT 21H

MOV BX, 0
NEXT7:
MOV AH, 01H
INT 21H
CMP AL, 0DH
JE NEXT6
MOV KEY[BX], AL
INC BX
JMP NEXT7

NEXT6:
MOV KEY_LEN, BL

MOV DL, 0DH
MOV AH, 02H
INT 21H
MOV DL, 0AH
INT 21H


MOV BX, 0
NEXT8:
MOV AH, 01H
INT 21H
CMP AL, 0DH
JE NEXT9
MOV PLAINTEXT[BX], AL
INC BX
JMP NEXT8

NEXT9:
MOV TEXT_LEN, BL 

MOV DL, 0DH
MOV AH, 02H
INT 21H
MOV DL, 0AH
INT 21H

RET

INPUT1 ENDP

;---------------------------------------------------------------------------------------------------------


OUTPUT_CIPHERTEXT PROC NEAR

MOV BX, 0

NEXT10:
PUSH BX

MOV AL, CIPHERTEXT[BX]
AND AL, 0F0H
SHR AL, 4
MOV BX, OFFSET LIST
XLAT
MOV DL, AL
MOV AH, 02H
INT 21H

POP BX
PUSH BX

MOV AL, CIPHERTEXT[BX]
AND AL, 0FH
MOV BX, OFFSET LIST
XLAT
MOV DL, AL
MOV AH, 02H
INT 21H

MOV AH, 02H
MOV DL, 'H'
INT 21H
MOV DL, ' '
INT 21H

POP BX 
INC BX
CMP BL, TEXT_LEN
JE NEXT11
JMP NEXT10
NEXT11:

MOV DL, 0DH
MOV AH, 02H
INT 21H
MOV DL, 0AH
INT 21H

RET
    
OUTPUT_CIPHERTEXT ENDP

;-------------------------------------------------------------------------------------------

INPUT2 PROC NEAR
MOV DX, OFFSET TIPS2
MOV AH, 09H
INT 21H

MOV BX, 0
NEXT16:
MOV AH, 01H
INT 21H
CMP AL, 0DH
JE NEXT17
MOV KEY[BX], AL
INC BX
JMP NEXT16

NEXT17:
MOV KEY_LEN, BL

MOV DL, 0DH
MOV AH, 02H
INT 21H
MOV DL, 0AH
INT 21H

MOV BX, 0

NEXT12:
MOV AH, 01H
INT 21H
CMP AL, 0DH
JE NEXT15

CMP AL, 'H'
JE NEXT12
CMP AL, ' '
JE NEXT12
CMP AL, 'A'
JNB NEXT13
SUB AL, 30H
JMP NEXT18
NEXT13:
SUB AL, 37H
NEXT18:
SHL AL, 4
MOV CL, AL
INT 21H
CMP AL, 'A'
JNB NEXT14
SUB AL, 30H
JMP NEXT19
NEXT14:
SUB AL, 37H
NEXT19:
ADD AL, CL
MOV RECIPHERTEXT[BX], AL
INC BX
JMP NEXT12

NEXT15:
MOV RETEXT_LEN, BL


MOV DL, 0DH
MOV AH, 02H
INT 21H
MOV DL, 0AH
INT 21H

RET

INPUT2 ENDP

;--------------------------------------------------------------------------------------------

DECIPHER PROC NEAR
    
MOV BX, 0;k
MOV SI, 0;i
MOV DI, 0;j
MOV CX, 256

NEXT20:
MOV AX, SI
INC AX
MOV DX, 0
DIV CX
MOV SI, DX
MOV AL, S[SI]
MOV AH, 0
ADD DI, AX
MOV AX, DI
MOV DX, 0
DIV CX
MOV DI, DX
MOV AL, S[SI]
MOV TEMP, AL
MOV AL, S[DI]
MOV S[SI], AL
MOV AL, TEMP
MOV S[DI], AL
MOV AL, S[SI]
ADD AL, S[DI]
JNC NEXT21
MOV AH, 1
JMP NEXT22
NEXT21:
MOV AH, 0
NEXT22:
MOV DX, 0
DIV CX
PUSH SI
MOV SI, DX
MOV AL, S[SI]
MOV AH, RECIPHERTEXT[BX]
XOR AH, AL
MOV REPLAINTEXT[BX], AH
POP SI
INC BX
CMP BL, RETEXT_LEN
JB NEXT20
RET    

DECIPHER ENDP

;-------------------------------------------------------------------------------------------
OUTPUT_REPLAINTEXT PROC NEAR

MOV BX, 0
NEXT24:
MOV AH, 02H
MOV DL, REPLAINTEXT[BX]
INT 21H
INC BX
CMP BL, RETEXT_LEN
JE NEXT23
JMP NEXT24
NEXT23:
RET

    
OUTPUT_REPLAINTEXT ENDP


CODE ENDS
END MAIN

其他

输入输出描述:
这个代码首先要求输入加密过程中使用的密钥与明文(长度256以内),以回车相间隔。然后代码运行后会输出密文(以16进制数方式)。由于RC4是一种异或实现的流密码,所以明文、密文长度相同。然后要求输入解密过程中使用的密钥与密文(这里的密钥与密文可以与上面输入输出密钥密文不同,但是输入相同的可以自检)。同样以回车相间隔。然后代码运行输出明文。
如何加密验证正确性:
我们知道一个二进制数异或两次另一个二进制数,仍是它本身。这也是RC4为何加解密过程相同的原因。但这也导致即使你加密解密过程不正确(与RC4不同),只要相同,便可以同样从密文中还原明文。所以自检无法说明程序正确性。
同时,在网上找到的线上RC4加密,输入同样的密钥、明文,加密结果都不尽相同。而且他们大多采用UTF-8等字符集,没有使用ASCII字符集的。所以无法相验证。
下面仅使用百度百科给出的C语言代码相印证。

#include <stdio.h>

/*初始化函数*/
void rc4_init(unsigned char*s,unsigned char*key, unsigned long Len)
{
    int i=0,j=0;
    //char k[256]={0};
    unsigned char k[256]={0};
    unsigned char tmp=0;
    for(i=0;i<256;i++) {
        s[i]=i;
        k[i]=key[i%Len];
    }
    for(i=0;i<256;i++) {
        j=(j+s[i]+k[i])%256;
        tmp=s[i];
        s[i]=s[j];//交换s[i]和s[j]
        s[j]=tmp;
    }
}

void rc4_crypt(unsigned char*s,unsigned char*Data,unsigned long Len)
{
    int i=0,j=0,t=0;
    unsigned long k=0;
    unsigned char tmp;
    for(k=0;k<Len;k++)
    {
        i=(i+1)%256;
        j=(j+s[i])%256;
        tmp=s[i];
        s[i]=s[j];//交换s[x]和s[y]
        s[j]=tmp;
        t=(s[i]+s[j])%256;
        Data[k]^=s[t];
    }
}
int main()
{
	unsigned char s[256];
	unsigned char key[6]={49,50,51,52,53,54};
	unsigned long len=6;
	unsigned char data[6]={48,49,48,49,48,49};
	rc4_init(s,key,len);
	/*for(int i=0;i<256;i++)
	{
		printf("%d ",s[i]);
	}
	putchar('\n');*/
	rc4_crypt(s,data,6);
	for(int i=0;i<6;i++)
	{
		printf("%d ",data[i]);
	}
	return 0;
 }

这里为了方便将密钥与明文直接写入代码中了。密钥为49、50、51、52、53、54(十进制),对应ASCII码的1、2、3、4、5、6(字符)。明文为48、49、48、49、48、49(十进制),对应ASCII码的0、1、0、1、0、1(字符)。与下图8086运行输入相对应。
C语言输出结果:
在这里插入图片描述
8086汇编输出结果:
在这里插入图片描述
如果将c语言输出结果转为16进制,则与8086上图输出结果一致。

其他

这个汇编程序涉及DOS调用的输入输出,以及返回DOS。使用的是emu8086编译器(debug方便)。所以移植其他不支持DOS调用或者返回DOS会出错的编译器软件时,可能会报错。修改对应位置即可。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值