取势 明道 优术

作者为 扶 凯 发表

我见到很多人有一些需求。就是想给自己的程序加密。比如商业程序和一些记录着关键信息的程序。这样让自己的源代码不可读,但又不想对程序的性能靠成什么大的影响。
当然在 Perl 中也有一堆的方法来实现这个功能。因为我写的跳板程序直接给 Key 写到程序本身,所以我不希望别人能见到我的 SSH 的 Key 。所以我对整个程序进行一定程度上的加密是很有必要的。在 PHP 中有一个很出名的东西叫 Zend,给整个程序加密成不可见的,我们现在自己来实现一个简化的 Zend。在 Perl 中我们有各种好用的模块帮我们实现这种功能。我现在给大家来介绍一个使用 Filter 模块来实现的这个源代码加密功能。

想详细了解这种东西是怎么工作的,可以看我的一处有关 Perl 的过滤器的译文 perlfilter. 简单来讲,就是在 Perl 最开始  use 一个模块,然后以后的东西都是加密过的代码。这些代码会使用这个模块来解码,解码完了然后才会读到 Perl 的解析器中。

使用方法,我们要先在代码加密程序中来定制一个自己的加密字符。并给修改过的 Filter 的模块安装到解码的服务器上。

1. 我们先下载并解压 Filter 模块

wget http://www.cpan.org/authors/id/R/RU/RURBAN/Filter-1.49.tar.gz
tar zxvf Filter-1.49.tar.gz
cd Filter-1.49


这时我们进入了这个模块。这个包中有一些文件,是我们要用到的。我们先修改和定制加密的字符。

2.  定制加密的字符

对于定制这个地方,需要修改二个文件,一个解密的 C 文件( decrypt/decrypt.xs ),一个是加密的程序。之所以要修改解密的 C 程序是因为解密的时候会调用这个 C 编译以后的 so 文件来解码。所以这也要求,对方的机器上的 Filter::decrypt 中引用的 so 是我们修改过以后。不用担心。因为是 so 文件,所以你定制的 key 别人并不知道,所以这样安全. 我们先打开这个文件。修改下面红圈的部分.

注意 BLOCKSIZE, 这个是指下面的字符的长度,有人讲修改了后,还是 Perl 说明这个人只是在原来的密码上加了一个字符,因为长段的原因,所以这个字符被删除了,所以只能使用 Perl 这个加密 key.
这个所生成的 so 文件,用于复制到其它的机器,如下的位置。

3. 加密我们自己的程序

在 decrypt 目录下有个 encrypt  的文件,我们也照样,打开并修改这个文件第 12 行也和上面的一样

修改完以后,对我们真实的程序,使用这个来加密。注意这个会删除原文件,你要保留好。比如我们原来的程序叫 test.pl.

#perl decrypt/encrypt  test.pl

这时生成的新文件,还是 test.pl 不过你打开看时都会是象下面这样。但是还是能正常的执行。

4. 在目标主机上安装上面定制过 decrypt.xs 的 Filter 的模块

标准的模块安装方式,记得要替换 descypt.xs 的你上面的加密程序相配。不然不能执行。替换 so 的文件也行。
在目标主机上

perl Makefile && make && make install

好了,这时给你上面加密过的 test.pl 复制过来,在这台机器上就能执行了。因为其它人并不知道你的加密字符(so 文件是编译后的)所以相对安全。注意保管好你的 Key 不要让其它人知道。

FQA: 自己加密的程序,没有原来的文件了,只有加密后的,怎么通过 key 来还原.下面提供一个反解程序

#!/usr/bin/perl

require 5.002;

use vars qw (
    $XOR
    $BLOCKSIZE
    $HEADERSIZE
    $CRYPT_MAGIC_1
    $CRYPT_MAGIC_2
    $size
    $mode
    $line
);

$XOR           = '你定制的 key';
$BLOCKSIZE     = length $XOR;
$HEADERSIZE    = 2;
$CRYPT_MAGIC_1 = 0xff;
$CRYPT_MAGIC_2 = 0x00;

foreach $file (@ARGV)
{
    open (F, "<$file") or die "Cannot open $file: $!\n";
    open (O, ">${file}.ne") or die "Cannot open ${file}.ne: $!\n";

    seek(F,0,0);
    $line = <F>;

    $block = ''; 
    read(F, $block, 24);
    while ($size = read(F, $block, $BLOCKSIZE) )
    {   
        print O ($block ^ substr($XOR, 0, length $block)) ;
    }   

    close F;
    close O;
}

如果你想做自己的解码和加密过滤器,请看这个文章:一次用C语言写source filter的成功尝试

来了就留个评论吧! 10个评论



    realzhang 2013年05月25日 的 04:16

    很好,收藏了!

    test@teset.com 2013年06月14日 的 12:29

    你好!我想问一下,如果我的Perl程序用Acme::Morse这样的模块进行加密,是不是很容易解密?

      扶 凯 2013年06月16日 的 14:45

      只要是动态程序,其实都比较容易

    Zhao 2014年02月21日 的 00:37

    修改下面红线的部分 图片失效了

    Chao 2014年04月10日 的 06:19

    修改下面红线的部分 图片失效了….麻烦重新贴一下吧!

    3618 2014年09月2日 的 14:09

    图片失效了,麻烦更新一下吧!

    3618 2014年09月2日 的 14:10

    这个脚本改密码之后就运行不了。

    3618 2014年09月2日 的 14:11

    密码从Perl改成别的好像不能正确解密

    潮/习惯 2014年10月22日 的 23:29

    第二张图片失效了,麻烦更新,谢谢!

    perlDBA 2014年11月28日 的 11:16

    第二张图片失效了,麻烦更新,谢谢!