文件加密/解密(多种实现)
加密/解密是一门技术很高的学科.我不懂,所以这样说,实际上也是吧?我没学过这方面的知识,但有兴趣,所以先以最简单的开始.用位运算的异或来对文件加密,再异或一次就还原.
好了,废话少说,下面是一个用汇编写的简单文件加密程序.
;******************************************
title 文件加密/解密程序
;******************************************
data segment
seed db ?
handle dw ?
bufferSize db 13
nameLen db ?
fileName db 14 dup(0)
tips db 'Please input the name of the encode/decode file!',0ah,0dh,'$'
seedMSG db 'Please input the number for encode/decode(such as 123)(<=255)',0ah,0dh,'$'
errorMSG db 0ah,0dh,'error','$'
buf db 256 dup(?)
len dw ?
fileLen dw 0
data ends
code segment
assume cs:code,ds:data
chooseFile proc
start: mov ax,data
mov ds,ax
mov ah,09h
lea dx,tips
int 21h
mov ah,0ah
lea dx,bufferSize
int 21h
mov bh,0
mov bl,nameLen
mov fileName,0
lea dx,fileName
mov ax,3d02h ;AL=0为读文件,AH=3DH是功能号
int 21h
jcerror ;若打开出错,转到去打开默认文件
mov Handle,ax
;输入加密密钥
mov ah,09h
lea dx,seedMSG
int 21h
mov ah,0ah
lea dx,bufferSize ;为节省,用fileName
int 21h
cmp nameLen,4
jnb error ;大于四则为错误输入
mov bh,0
mov bl,nameLen
mov fileName,0
mov fileName,10
mov fileName,20;这三个设置使无输入时也有0,10,20值
lea di,fileName
sub ,30h ;下面是转换数字,但可能溢出,且不管了.
mov ah,100
mov al,
mul ah
mov bx,ax
sub ,30h
mov ah,10
mov al,
mul ah
add bx,ax
add al,
sub al,30h
mov seed,al
read: mov bx,Handle
lea dx,buf
mov cx,255 ;指定读文件字节数
mov ah,3fh
int 21h
jcerror
cmp ax,0
jzover
mov len,ax ;ax=实际读到的字符数
mov cx,len ;加密
lea di,buf
mov al,seed
encode: xor ,al
inc di
loop encode
;CX=0,移动文件指针
mov dx,fileLen ;cx:dx为文件指针移动长度
mov ax,4200h
int 21h
mov cx,len ;加密后写入文件
mov bx,handle
lea dx,buf
mov ah,40h ;写文件
int 21h
jc error
mov ax,len
add fileLen,ax
jmp read
error:
lea dx,errorMSG
mov ah,09h
int 21h
over: mov ah,4ch
int 21h
chooseFile endp
code ends
end start
以上程序只对文本文件的加密/解密测试通过.汇编用DOS中断调用能能不能对二进制文件操作呢?好像不能.更高级的方法应该可以实现(可我不会).如果用C,C++或JAVA就可以比较容易实现对二进制文件进行加密/解密了.
(待续...) 用C语言实现如下:
/*encrypt.c file */
#include<stdio.h>
#include<stdlib.h>
#define BUFFER 2048
int main(int argc,char* argv[])
{
FILE *src,*dest;
unsigned char buffer;
char seeds;
long size; int i,len,temp;
if(argc!=3)
{
printf(\"usage:Encrypt source destination\\n\");
exit(1);
}
if ((src=fopen(argv,\"rb+\"))==NULL)
{
printf(\"Cannot open the file: %s\",argv);
exit(1);
}
if ((dest=fopen(argv,\"wb+\"))==NULL)
{
printf(\"Create file error\");
exit(1);
}
printf(\"请输入密钥\\n\");
gets(seeds);
len=strlen(seeds);
do{
size = fread(buffer,1,BUFFER,src);
for (i=0;i<size;i++)
{
buffer=buffer^seeds;
}
fwrite(buffer,1,size,dest);
}while( size==BUFFER );
fclose(src);
fclose(dest);
printf(\"ok\\n\");
return 0;
}
这个就可以对二进制文件进行操作了.而密码长度也比用汇编的好些.
[ 本帖最后由 powerwind 于 2006-1-10 01:20 编辑 ] 支持原创。
我对加密/解密也了解甚少,尽管这个学期有一科相关学科,但由于自己态度不端正没学好。至今我在实际应用中涉及的所谓加密就仅仅局限于MD5。。。
我先仔细研究下先。。。楼下继续讨论。。。 用VB.NET来实现也差不多.
当然,这个程序少不了界面,下面只给出主要代码.
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
If OpenFile.ShowDialog = DialogResult.OK Then
TextBox1.Text = OpenFile.FileName
End If
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
If SaveFile.ShowDialog = DialogResult.OK Then
TextBox2.Text = SaveFile.FileName
End If
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.AcceptButton = Nothing
src = TextBox1.Text
dest = TextBox2.Text
If TextBox3.Text.Length = 0 Then
MsgBox(\"请输入密钥!\", MsgBoxStyle.OKOnly)
Exit Sub
ElseIf TextBox1.Text.Length = 0 Or TextBox2.Text.Length = 0 Then
MsgBox(\"请确定已输入源文件与目标文件路径\", MsgBoxStyle.Critical)
Exit Sub
ElseIf Not File.Exists(src) Then
MsgBox(\"源文件不存在!\", MsgBoxStyle.Critical)
Exit Sub
ElseIf Not TextBox3.Text.Equals(TextBox4.Text) Then
MsgBox(\"你输入密钥不一致!\", MsgBoxStyle.OKOnly)
Exit Sub
End If
Try
Dim temp As String
temp = TextBox3.Text
seedsLen = Len(temp)
For i = 0 To seedsLen - 1 Step 1
seeds(i) = Asc(temp.Substring(i, 1))
Next i
Call encrypt()
Catch ex As Exception
MsgBox(ex.Message & \"(不支持中文字符)\", MsgBoxStyle.OKOnly)
End Try
End Sub
#Region \"加密/解密子过程encrypt\"
Private Sub encrypt()
Dim count As Int32
Dim buf(2048) As Byte
Try
Dim r As BinaryReader = New BinaryReader(New FileStream(src, FileMode.Open, FileAccess.Read))
Dim w As BinaryWriter = New BinaryWriter(New FileStream(dest, FileMode.Create, FileAccess.Write))
Do
count = r.Read(buf, 0, 2048)
For i = 0 To count Step 1
buf(i) = buf(i) Xor seeds(i Mod seedsLen)
Next i
w.Write(buf, 0, count)
Loop Until count = 0
r.Close()
w.Close()
MsgBox(\"成功保存了一个文件!\", MsgBoxStyle.OKOnly)
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical)
End Try
End Sub
#End Region
呵呵
可以改成其他语言版本 呵呵
用rsa加密小文件还是挺好玩的。很多软件的注册原理就是如此。楼主有空可以试试,更有挑战性的莫过于其大数运算了,够你使用c++很多技巧了,如果不会就去网上down个大数运算库。
简单的注册原理就是得到机器码(如cpu序号,硬盘序列号等等),发送给你你用私钥加密后发送给软件使用者。
软件使用者输入密文后,软件使用公钥解密然后判断机器码是否一致,然后开启注册后功能。(此法只防君子不防小人)。 java的代码
/*加密/解密程序//*/
import java.io.*;
public class Encrypt
{
public static void main(String[]args)
{
byte[]seeds=new byte;
byte[]buf=new byte;
int seedsLen=0;
InputStreamReader in;
FileInputStream fis;
FileOutputStream fos;
if(args.length!=2){
System.out.println(\"usage:java Encrypt source dest\");
System.exit(1);
}
System.out.println(\"请输入密钥\");
try{
seedsLen=System.in.read(seeds);
seedsLen-=2; //去掉回车符
}catch(Exception ex){ex.printStackTrace();}
try{
fis=new FileInputStream(new File(args));
fos=new FileOutputStream(new File(args));
int len=0;
do{
len=fis.read(buf);
for(int i=0;i<len;i++){
//JAVA只支持对整数进行异或运算,只好这样转换来转换去
buf=(byte)(seeds^buf);
}
fos.write(buf,0,len);
}while(len==1024);
fis.close();
fos.close();
}catch(Exception ex){ex.printStackTrace();}
}
}//*/
[ 本帖最后由 powerwind 于 2006-1-11 23:33 编辑 ]
页:
[1]