工大后院

 找回密码
 加入后院

扫一扫,访问微社区

QQ登录

只需一步,快速开始

搜索
查看: 1875|回复: 6

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

[复制链接]
发表于 2006-1-9 11:49 | 显示全部楼层 |阅读模式
加密/解密是一门技术很高的学科.我不懂,所以这样说,实际上也是吧?我没学过这方面的知识,但有兴趣,所以先以最简单的开始.
用位运算的异或来对文件加密,再异或一次就还原.
好了,废话少说,下面是一个用汇编写的简单文件加密程序.


  1. ;******************************************
  2. title 文件加密/解密程序
  3. ;******************************************

  4. data segment
  5. seed                db ?
  6. handle                dw ?
  7. bufferSize                        db 13
  8. nameLen                db ?
  9. fileName                        db 14 dup(0)
  10. tips                db 'Please input the name of the encode/decode file!',0ah,0dh,'$'
  11. seedMSG                db 'Please input the number for encode/decode(such as 123)(<=255)',0ah,0dh,'$'
  12. errorMSG                        db 0ah,0dh,'error','$'
  13. buf                db 256 dup(?)
  14. len                dw ?
  15. fileLen                dw 0
  16. data ends

  17. code segment
  18. assume cs:code,ds:data
  19. chooseFile proc
  20. start:        mov ax,data
  21.         mov ds,ax
  22.        
  23.         mov ah,09h
  24.         lea dx,tips
  25.         int 21h

  26.         mov ah,0ah
  27.         lea dx,bufferSize
  28.         int 21h
  29.         mov bh,0
  30.         mov bl,nameLen
  31.         mov fileName[bx],0

  32.         lea dx,fileName
  33.         mov ax,3d02h        ;AL=0为读文件,AH=3DH是功能号
  34.         int 21h
  35.         jc  error        ;若打开出错,转到去打开默认文件
  36.         mov Handle,ax
  37.                         ;输入加密密钥
  38.         mov ah,09h
  39.         lea dx,seedMSG
  40.         int 21h
  41.         mov ah,0ah
  42.         lea dx,bufferSize        ;为节省,用fileName
  43.         int 21h
  44.         cmp nameLen,4
  45.         jnb error                      ;大于四则为错误输入
  46.         mov bh,0
  47.         mov bl,nameLen
  48.         mov fileName[bx],0
  49.         mov fileName[bx+1],10
  50.         mov fileName[bx+2],20  ;这三个设置使无输入时也有0,10,20值
  51.         lea di,fileName

  52.         sub [di],30h                ;下面是转换数字,但可能溢出,且不管了.
  53.         mov ah,100
  54.         mov al,[di]
  55.         mul ah
  56.         mov bx,ax
  57.         sub [di],30h
  58.         mov ah,10
  59.         mov al,[di+1]
  60.         mul ah
  61.         add bx,ax
  62.         add al,[di+2]
  63.         sub al,30h
  64.         mov seed,al
  65.        
  66. read:        mov bx,Handle
  67.         lea dx,buf
  68.         mov cx,255        ;指定读文件字节数
  69.         mov ah,3fh
  70.         int 21h
  71.         jc  error
  72.         cmp ax,0
  73.         jz  over
  74.         mov len,ax        ;ax=实际读到的字符数

  75.         mov cx,len        ;加密
  76.         lea di,buf
  77.         mov al,seed
  78. encode:        xor [di],al
  79.         inc di
  80.         loop encode
  81.                         ;CX=0,移动文件指针
  82.         mov dx,fileLen            ;cx:dx为文件指针移动长度
  83.         mov ax,4200h
  84.         int 21h
  85.         mov cx,len                        ;加密后写入文件
  86.         mov bx,handle
  87.         lea dx,buf
  88.         mov ah,40h               ;写文件
  89.         int 21h
  90.         jc error
  91.         mov ax,len
  92.         add fileLen,ax
  93.         jmp read
  94. error:
  95.         lea dx,errorMSG
  96.         mov ah,09h
  97.         int 21h
  98. over:        mov ah,4ch
  99.         int 21h
  100. chooseFile endp
  101.                 code ends
  102.                 end start
复制代码


以上程序只对文本文件的加密/解密测试通过.汇编用DOS中断调用能能不能对二进制文件操作呢?好像不能.更高级的方法应该可以实现(可我不会).如果用C,C++或JAVA就可以比较容易实现对二进制文件进行加密/解密了.
(待续...)
 楼主| 发表于 2006-1-9 12:58 | 显示全部楼层
用C语言实现如下:


  1. /*encrypt.c file */
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #define BUFFER 2048

  5. int main(int argc,char* argv[])
  6. {   
  7.     FILE *src,*dest;
  8.     unsigned char buffer[BUFFER];
  9.    char seeds[100];
  10.     long size; int i,len,temp;
  11.     if(argc!=3)
  12.                 {
  13.                printf("usage:Encrypt source destination\\n");
  14.                exit(1);
  15.         }
  16.                 if ((src=fopen(argv[1],"rb+"))==NULL)
  17.                         {
  18.                            printf("Cannot open the file: %s",argv[1]);
  19.                            exit(1);
  20.                         }
  21.                 if ((dest=fopen(argv[2],"wb+"))==NULL)
  22.                         {
  23.                            printf("Create file error");
  24.                            exit(1);
  25.                         }
  26.     printf("请输入密钥\\n");
  27.    gets(seeds);
  28.    len=strlen(seeds);     
  29.     do{
  30.         size = fread(buffer,1,BUFFER,src);
  31.         for (i=0;i<size;i++)
  32.         {
  33.             buffer[i]=buffer[i]^seeds[i%len];
  34.         }
  35.         fwrite(buffer,1,size,dest);
  36.         }while( size==BUFFER );
  37.         fclose(src);
  38.         fclose(dest);
  39.         printf("ok\\n");
  40.         return 0;
  41. }
复制代码

这个就可以对二进制文件进行操作了.而密码长度也比用汇编的好些.

[ 本帖最后由 powerwind 于 2006-1-10 01:20 编辑 ]
回复

使用道具 举报

发表于 2006-1-9 13:45 | 显示全部楼层
支持原创。

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

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

使用道具 举报

 楼主| 发表于 2006-1-10 23:33 | 显示全部楼层
用VB.NET来实现也差不多.
当然,这个程序少不了界面,下面只给出主要代码.

  1.     Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
  2.         If OpenFile.ShowDialog = DialogResult.OK Then
  3.             TextBox1.Text = OpenFile.FileName
  4.         End If
  5.     End Sub

  6.     Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
  7.         If SaveFile.ShowDialog = DialogResult.OK Then
  8.             TextBox2.Text = SaveFile.FileName
  9.         End If
  10.     End Sub

  11.     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
  12.         Me.AcceptButton = Nothing
  13.         src = TextBox1.Text
  14.         dest = TextBox2.Text
  15.         If TextBox3.Text.Length = 0 Then
  16.             MsgBox("请输入密钥!", MsgBoxStyle.OKOnly)
  17.             Exit Sub
  18.         ElseIf TextBox1.Text.Length = 0 Or TextBox2.Text.Length = 0 Then
  19.             MsgBox("请确定已输入源文件与目标文件路径", MsgBoxStyle.Critical)
  20.             Exit Sub
  21.         ElseIf Not File.Exists(src) Then
  22.             MsgBox("源文件不存在!", MsgBoxStyle.Critical)
  23.             Exit Sub
  24.         ElseIf Not TextBox3.Text.Equals(TextBox4.Text) Then
  25.             MsgBox("你输入密钥不一致!", MsgBoxStyle.OKOnly)
  26.             Exit Sub
  27.         End If
  28.         Try
  29.             Dim temp As String
  30.             temp = TextBox3.Text
  31.             seedsLen = Len(temp)
  32.             For i = 0 To seedsLen - 1 Step 1
  33.                 seeds(i) = Asc(temp.Substring(i, 1))
  34.             Next i
  35.             Call encrypt()
  36.         Catch ex As Exception
  37.             MsgBox(ex.Message & "(不支持中文字符)", MsgBoxStyle.OKOnly)
  38.         End Try
  39.     End Sub

  40. #Region "加密/解密子过程encrypt"
  41.     Private Sub encrypt()
  42.         Dim count As Int32
  43.         Dim buf(2048) As Byte
  44.         Try
  45.             Dim r As BinaryReader = New BinaryReader(New FileStream(src, FileMode.Open, FileAccess.Read))
  46.             Dim w As BinaryWriter = New BinaryWriter(New FileStream(dest, FileMode.Create, FileAccess.Write))

  47.             Do
  48.                 count = r.Read(buf, 0, 2048)
  49.                 For i = 0 To count Step 1
  50.                     buf(i) = buf(i) Xor seeds(i Mod seedsLen)
  51.                 Next i
  52.                 w.Write(buf, 0, count)
  53.             Loop Until count = 0

  54.             r.Close()
  55.             w.Close()
  56.             MsgBox("成功保存了一个文件!", MsgBoxStyle.OKOnly)
  57.         Catch ex As Exception
  58.             MsgBox(ex.Message, MsgBoxStyle.Critical)
  59.         End Try
  60.     End Sub
  61. #End Region

复制代码
回复

使用道具 举报

发表于 2006-1-11 14:34 | 显示全部楼层
呵呵
可以改成其他语言版本
回复

使用道具 举报

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

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

使用道具 举报

 楼主| 发表于 2006-1-11 19:22 | 显示全部楼层
java的代码

  1. /*加密/解密程序//*/
  2. import java.io.*;
  3. public class Encrypt
  4. {
  5.         public static void main(String[]args)
  6.         {
  7.                 byte[]seeds=new byte[100];
  8.                 byte[]buf=new byte[1024];
  9.                 int seedsLen=0;
  10.                 InputStreamReader in;
  11.                 FileInputStream fis;
  12.                 FileOutputStream fos;
  13.                 if(args.length!=2){
  14.                         System.out.println("usage:java Encrypt source dest");
  15.                         System.exit(1);
  16.                 }

  17.                 System.out.println("请输入密钥");
  18.                 try{
  19.                 seedsLen=System.in.read(seeds);
  20.                 seedsLen-=2;          //去掉回车符
  21.                 }catch(Exception ex){ex.printStackTrace();}
  22.                 try{
  23.                         fis=new FileInputStream(new File(args[0]));
  24.                         fos=new FileOutputStream(new File(args[1]));
  25.                         int len=0;
  26.                         do{
  27.                                         len=fis.read(buf);
  28.                                 for(int i=0;i<len;i++){
  29.                                                   //JAVA只支持对整数进行异或运算,只好这样转换来转换去
  30.                                 buf[i]=(byte)(seeds[i%seedsLen]^buf[i]);
  31.                                         }
  32.                                 fos.write(buf,0,len);
  33.                         }while(len==1024);
  34.                         fis.close();
  35.                         fos.close();
  36.                 }catch(Exception ex){ex.printStackTrace();}

  37.         }

  38. }//*/

复制代码

[ 本帖最后由 powerwind 于 2006-1-11 23:33 编辑 ]
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入后院

本版积分规则

QQ|Archiver|手机版|小黑屋|广告业务Q|工大后院 ( 粤ICP备10013660号 )

GMT+8, 2025-5-14 11:22

Powered by Discuz! X3.5

Copyright © 2001-2024 Tencent Cloud.

快速回复 返回顶部 返回列表