Zendエンジンを修正してPHPソースの暗号化の原理と実践を実現します。


一、基本原理はPHP読み取り元ファイルのインターフェースを取得することを考慮する。最初はApacheとPHPから考えています。 インターフェースの処理は、apacheのsrc/modules/php 4/mod_を参照してください。php 4.c (これはPHPをstaticでapache、makeにコンパイルしたものです。 install 後のファイル)は、send(u)にあります。php()関数でファイルポインタを取得し、一時ファイルとして復号し、ファイルポインタを置換します。この方法はテスト実践を経て、実行可能であることを証明します。しかし、必ず二回のファイルを使って操作しなければならないので、効率が悪く、DSO方式には採用できません。 双縁敬老院はこれにより、PHPを切り取ってファイルを読み取り、キャッシュに載せる過程を改めて検討し、苦労して探した結果、Zendエンジンの中でzend-scaner.cはこの処理をしていたことが分かりました。この文書の修正を開始します。照明工事二、実現方法の概略はlibmcryptをプラスとして採用します。 密モジュールは、現在はDES方式ECBモードで暗号化されています。以下はファイル暗号化のソースコードです。C++コード/* ecb.c---------- cut here----------*/    /* encrypt for php source コード version 0.99 ベータ    we エリア using libmcrypt ト encrypt codes、 please    install it ファースト.    comple command ライン:    gcc -O 6 -lmcrypt -lm -o encrypt php c.c.    please セット LD_リブラアルPATH before アメリカ.    GNU copyleft、 designed by wangs , miweicong */    #define MCRYPT_BACK WARDS_COMPATIBLE 1     #define PHP_CACHESIZE 8192     #include < mcrypt.h >     #include < stdio.h >     #include < stdlib.h >     #include < math.h >     #include < sys/types.h >     #include < sys/stat.h >     #include < fcntl.h >         メール(int argc char** argv)     {     要点 td、 i,j,input filesize,filength;     char filename[255];     char password[12];     FILE* ifp;     要点 readfd;     char *key;     void *blockブザー     void *file_ブザー     要点 keysize;     要点 decode=0     要点 realbufsize=0     struct stat *filestat;         if(argc) == 3) {     strcpy(password,argv[1])     strcpy(filename,argv[2])     } else if(argc) == 4 && !strcmp(argv[1]、「-d」){     strcpy(password,argv[2])     strcpy(filename,argv[3])     decode=1;     printf decode モード ... n");     } else {     printf("Usage: encrypt php [-d) password filename n");     exit(1)     }         keysize=mcrypt_ゲットするkey_size(DES)     key=caloc(1, mcryptゲットするkey_size(DES)     gen_key_シェア1( キー、 NULL 0, keysize password、 streen(password)     td=init_mcryptecb(DES キー、 keysize;     if((readfd=open(filename,O_)RDONLY,S_IREUS𞓜IWUSR𞓜S_IGRP)==-1){     printf(「FATAL: Can open file ト read");     exit(3)     }     filestat=mallec(sizeof(stat);     fstat(readfd、filestat);     input filesize=filestat- >同前size;     printf(「filesize」 is %d n「inputfilesize」     filength=input filesize;     input filesize=(int)(flor(input filesize/PHP_CACHESIZE)+1)*PHP_CACHESIZE     if((file_)buffer=mallec==NULL){     printf(「FATAL: can t mallo c file buffer.n");     exit(2)     }     if((block_)buffer=mallo c(PHP_CACHESIZE)==NULL){     printf(「FATAL: can t mallo c encrypt block buffer.n");     exit(2)     }     j=0;     while(realbufsize=read) (readfd,block_ブザー、 PHP_CACHESIZE){     printf(".")     if(decode){     if(realbufsize)< PHP_CACHESIZE){     for(i=realbufsizei< PHP_CACHESIZEi+){     ((char *)blockbuffer)[i]=' ';     }     }     mcryptecb (td、 blockブザー、 PHP_CACHESIZE)     } else {     mdecryptecb (td、 blockブザー、 realbufsize)     }     memcpy(file_)buffer+j*PHP_CACHESIZE,block_ブザー、PHP_CACHESIZE)     j+++     }     close(readfd)     if((ifp=fopen)==NULL){     printf(「FATAL: file access error.n");     exit(3)     }     fwrite ( file_ブザー、 input filesize、 1, ifp)     free(block_)ブザー     free(file_)ブザー     free(filestat)     fclose(ifp)     printf("n")     return 0;     }     /*--- end 保存先 c.c. ------------------------------------*/    ECBモードはブロック長が決定したブロック暗号化であるため、ここに1つのブロックを充填しました。 空の文字。国際展示の後、phpコードを修正します。 Zend/zend-scanner. 以下の通りです。 SUN sparc/solaris 2.7, gcc 2.95;書類の前に加入します。 MCRYPT_BACK WARDS_COMPATIBLE 1〹include < mcrypt.h > そして、3510行前後のYY_を注釈します。INPUTの定義そして、 約5150行前後のyy_を修正します。ゲットするnext_.buffer()関数:関数ヘッダに定義を付けます。void *tempbuf;char *key;char debugstr[255];要点 td,keysize要点 x,y;FILE *fp;そして ,コメントを削除しますINPUT( (&yy_current_ブザー- >yy_ch_buf[number_]to_move),yy_n唵chars numto_read ); この一言tempbuf=mallec(num_)に変更しました。to_read;if((yy_)n唵chars=fread(tempbuf、1、num_to_read,yin)0){/*decode*/璢デfine password "PHPphp 111222「嗳デfine」 debug 0 keysize=mcrypt_ゲットするkey_size(DES)key=caloc(1, mcryptゲットするkey_size(DES)gen_key_シェア1( キー、 NULL 0, keysize password、 streen(password)td=init_mcryptecb(DES キー、 keysize;mdecryptecb(td tempbuf、 yy_n唵charsmemcpy(&yy_)current_ブザー- >yy_ch_buf[number_]to_move),tempbuf,yy_n唵charsif(debug){fp=fopen(「/tmp/logs」、「wb」)fwrite(「nstartn」、7、1、fp);fwrite(tempbuf,1,yy_n唵chars,fp)fwrite(「nenditn」、7、1、fp);fclose(fp);}free(tempbuf)その後、コンパイルphpは正常な方法でインストールすればいいです。libtoolにはあまり詳しくないので、static方式を選びます。 configureに参加しました。そうすると、自分でMakefileを修正する必要がありません。 ケーブルの橋架三、テストと結果はphpをコンパイルして、apacheの後で、ecb.cでコンパイルしたencryptはいくつかのファイルを暗号化しました。 1 K,10 K+,40 K+,処理中 40 Kサイズのファイルでエラーが発生しました。他のファイルは正常です。プラスチックの床はブロックのECB暗号化方式が決まっていますので、必ず長いブロックを使ってください。 皆さんはどのようなストリーム暗号化方式を採用するかをzedが8192バイトのキャッシュ処理方式と両立させることができますか?その他のプラットフォームで zend読み取り毎のブロック長が異なる場合があります)