powerwind 发表于 2006-1-9 11:49

文件加密/解密(多种实现)

加密/解密是一门技术很高的学科.我不懂,所以这样说,实际上也是吧?我没学过这方面的知识,但有兴趣,所以先以最简单的开始.
用位运算的异或来对文件加密,再异或一次就还原.
好了,废话少说,下面是一个用汇编写的简单文件加密程序.


;******************************************
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就可以比较容易实现对二进制文件进行加密/解密了.
(待续...)

powerwind 发表于 2006-1-9 12:58

用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 编辑 ]

wool王 发表于 2006-1-9 13:45

支持原创。

我对加密/解密也了解甚少,尽管这个学期有一科相关学科,但由于自己态度不端正没学好。至今我在实际应用中涉及的所谓加密就仅仅局限于MD5。。。

我先仔细研究下先。。。楼下继续讨论。。。

powerwind 发表于 2006-1-10 23:33

用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

盼望 发表于 2006-1-11 14:34

呵呵
可以改成其他语言版本

sasadong 发表于 2006-1-11 17:29

呵呵
用rsa加密小文件还是挺好玩的。很多软件的注册原理就是如此。楼主有空可以试试,更有挑战性的莫过于其大数运算了,够你使用c++很多技巧了,如果不会就去网上down个大数运算库。

简单的注册原理就是得到机器码(如cpu序号,硬盘序列号等等),发送给你你用私钥加密后发送给软件使用者。
软件使用者输入密文后,软件使用公钥解密然后判断机器码是否一致,然后开启注册后功能。(此法只防君子不防小人)。

powerwind 发表于 2006-1-11 19:22

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]
查看完整版本: 文件加密/解密(多种实现)