PHP-Beast 加密你的PHP源代码

有时候我们的代码会放到代理商上, 所以很有可能代码被盗取,或者我们写了一个商业系统而且不希望代码开源,所以这时候就需要加密我们的代码。 另外PHP-Beast是完全免费和开源的, 当其不能完成满足你的需求时, 可以修改其代码而满足你的要求。 wget https://github.com/liexusong/php-beast/archive/master.zip unzip master.zip cd php-beast-master phpize ./configure --with-php-config=/usr/local/php/bin/php-config make sudo make install 注意!编译前一定要修改key.c里的authkey这个加密key,可以避免被 破解: 当然DES加密也是可以被破解的,但耗时耗力,并不容易,所以说php-beast加密的代码相对来说还是比较安全的. authkey不同,生成的beast.so也就不同,beast.so加密的代码必须使用它自己才能运行. 不知道authkey,就算拿到对应的beast.so,应该也是无法破解PHP文件的. 修改php.ini配置文件,加入配置项:extension=beast.so 重启php-fpm sudo kill -USR2 `/usr/local/php/var/run/php-fpm.pid` 用工具包中的encrypt_project.php工具来加密你的项目,你只需要输入项目的路径和输出的项目路径即可(这个工具只会加密PHP文件,其他文件只会简单的复制)加密完之后 php-beast 当然你可能不希望加密项目的所有PHP源文件,所以你可以使用PHP-Beast模块提供的beast_encode_file()函数来加密其中的某个 文件,使用方法:beast_encode_file($input_file, $output_file),$input_file是要加密的文件,$output_file是要输出加密后的文件。 把源码加密后就可以放到服务器上运行了。另外PHP-Beast模块提供缓存功能,我们可以在php.ini文件中修改缓存的大小来控制PHP-Beast模块可以使用的缓存。如: [beast] beast.cache_size = 20000   们可以使用beast_cache_status()函数来查看缓存的状态。 最新的PHP-Beast 0.6主要修改了一些bug和增加了一些配置项: 1. 设置缓存大小可以使用单位, 例如: beast.cache_size = 10m; 2. 可以在配置文件中禁止beast模块, 例如: beast.enable = Off; 3. 增加了日志记录功能, 可以使用beast.log_file配置项指定日志文件. 4. 使用文件锁解决原来信号量锁导致的bug, 可以使用beast.lock_path来指定锁路径.   转自 http://ju.outofmemory.cn/entry/47761

pkcs8 密钥生成 用于RSA非对称加密

PKCS #8 使用 ASN.1 的 DER 编码规则。
openssl.exe 可以用来生成 PEM 格式的 RSA 密钥对。
1、生成私钥pem,  执行命令openssl genrsa -out rsa_private_key.pem 1024
2、生成公钥,执行命令openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
3、将RSA私钥转换成PKCS8格式,命令执行openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt PHP服务端语言读取私钥不需要PKCS8转换。

PHP加密解密字符串

项目中有时我们需要使用PHP将特定的信息进行加密,也就是通过加密算法生成一个加密字符串,这个加密后的字符串可以通过解密算法进行解密,便于程序对解密后的信息进行处理。 最常见的应用在用户登录以及一些API数据交换的场景。 最常见的应用在用户登录以及一些API数据交换的场景。 笔者收录了一些比较经典的PHP加密解密函数代码,分享给大家。加密解密原理一般都是通过一定的加密解密算法,将密钥加入到算法中,最终得到加密解密结果。 1、非常给力的authcode加密函数,Discuz!经典代码(带详解): function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) { // 动态密匙长度,相同的明文会生成不同密文就是依靠动态密匙 $ckey_length = 4; // 密匙 $key = md5($key ? $key : $GLOBALS['discuz_auth_key']); // 密匙a会参与加解密 $keya = md5(substr($key, 0, 16)); // 密匙b会用来做数据完整性验证 $keyb = md5(substr($key, 16, 16)); // 密匙c用于变化生成的密文 $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : ''; // 参与运算的密匙 $cryptkey = $keya.md5($keya.$keyc); $key_length = strlen($cryptkey); // 明文,前10位用来保存时间戳,解密时验证数据有效性,10到26位用来保存$keyb(密匙b), //解密时会通过这个密匙验证数据完整性 // 如果是解码的话,会从第$ckey_length位开始,因为密文前$ckey_length位保存 动态密匙,以保证解密正确 $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string; $string_length = strlen($string); $result = ''; $box = range(0, 255); $rndkey = array(); // 产生密匙簿 for($i = 0; $i <= 255; $i++) { $rndkey[$i] = ord($cryptkey[$i % $key_length]); } // 用固定的算法,打乱密匙簿,增加随机性,好像很复杂,实际上对并不会增加密文的强度 for($j = $i = 0; $i < 256; $i++) { $j = ($j + $box[$i] + $rndkey[$i]) % 256; $tmp = $box[$i]; $box[$i] = $box[$j]; $box[$j] = $tmp; } // 核心加解密部分 for($a = $j = $i = 0; $i < $string_length; $i++) { $a = ($a + 1) % 256; $j = ($j + $box[$a]) % 256; $tmp = $box[$a]; $box[$a] = $box[$j]; $box[$j] = $tmp; // 从密匙簿得出密匙进行异或,再转成字符 $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); } if($operation == 'DECODE') { // 验证数据有效性,请看未加密明文的格式 if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) { return substr($result, 26); } else { return ''; } } else { // 把动态密匙保存在密文里,这也是为什么同样的明文,生产不同密文后能解密的原因 // 因为加密后的密文可能是一些特殊字符,复制过程可能会丢失,所以用base64编码 return $keyc.str_replace('=', '', base64_encode($result)); } } 函数authcode($string, $operation, $key, $expiry)中的$string:字符串,明文或密文;$operation:DECODE表示解密,其它表示加密;$key:密匙;$expiry:密文有效期。 用法: $str = 'abcdef'; $key = 'www.helloweba.com'; echo authcode($str,'ENCODE',$key,0); //加密 $str = '56f4yER1DI2WTzWMqsfPpS9hwyoJnFP2MpC8SOhRrxO7BOk'; echo authcode($str,'DECODE',$key,0); //解密 2、加解密函数encrypt(): function encrypt($string,$operation,$key=''){ $key=md5($key); $key_length=strlen($key); $string=$operation=='D'?base64_decode($string):substr(md5($string.$key),0,8).$string; $string_length=strlen($string); $rndkey=$box=array(); $result=''; for($i=0;$i<=255;$i++){ $rndkey[$i]=ord($key[$i%$key_length]); $box[$i]=$i; } for($j=$i=0;$i<256;$i++){ $j=($j+$box[$i]+$rndkey[$i])%256; $tmp=$box[$i]; $box[$i]=$box[$j]; $box[$j]=$tmp; } for($a=$j=$i=0;$i<$string_length;$i++){ $a=($a+1)%256; $j=($j+$box[$a])%256; $tmp=$box[$a]; $box[$a]=$box[$j]; $box[$j]=$tmp; $result.=chr(ord($string[$i])^($box[($box[$a]+$box[$j])%256])); } if($operation=='D'){ if(substr($result,0,8)==substr(md5(substr($result,8).$key),0,8)){ return substr($result,8); }else{ return''; } }else{ return str_replace('=','',base64_encode($result)); } } 函数encrypt($string,$operation,$key)中$string:需要加密解密的字符串;$operation:判断是加密还是解密,E表示加密,D表示解密;$key:密匙。 用法: $str = 'abc'; $key = 'www.helloweba.com'; $token = encrypt($str, 'E', $key); echo '加密:'.encrypt($str, 'E', $key); echo '解密:'.encrypt($str, 'D', $key); 此外,大家还可以参考以下文章中关于PHP加密解密的介绍: php加密解密:http://www.oschina.net/code/snippet_162279_7186http://www.helloweba.com/view-blog-255.html 精​心​整​理​的​三​个​P​H​P​加​密​解​密​函​数​,​功​能​很​强​大: http://wenku.baidu.com/link?url=QCClQ5KAuE1GO2-k1zhzYFP-7jqXM2UDOuz3rnBoWZJL750MEFKM-lSq7ZL35AfBTuInwRU_yKs65ZYH4dOU18N9hElprUHesSjSaI5F5Oe 原文地址 http://www.helloweba.com/view-blog-255.html

OpenSSL小结

公司一个项目要进行交易数据传输,因为这个项目银行那边也是刚刚开始启动,所有的支持只有一个传输字段的说明文档,好吧,总的有人做事不是嘛,于是接口开发正式展开,第一步的难点就是加密解密,我选择使用OpenSSL. OpenSSL初接触的人恐怕最难的在于先理解各种概念 公钥/私钥/签名/验证签名/加密/解密/非对称加密 我们一般的加密是用一个密码加密文件,然后解密也用同样的密码.这很好理解,这个是对称加密.而有些加密时,加密用的一个密码,而解密用另外一组密码,这个叫非对称加密,意思就是加密解密的密码不一样.初次接触的人恐怕无论如何都理解不了.其实这是数学上的一个素数积求因子的原理的应用,如果你一定要搞懂,百度有大把大把的资料可以看,其结果就是用这一组密钥中的一个来加密数据,可以用另一个解开.是的没错,公钥和私钥都可以用来加密数据,相反用另一个解开,公钥加密数据,然后私钥解密的情况被称为加密解密,私钥加密数据,公钥解密一般被称为签名和验证签名. 因为公钥加密的数据只有它相对应的私钥可以解开,所以你可以把公钥给人和人,让他加密他想要传送给你的数据,这个数据只有到了有私钥的你这里,才可以解开成有用的数据,其他人就是得到了,也看懂内容.同理,如果你用你的私钥对数据进行签名,那这个数据就只有配对的公钥可以解开,有这个私钥的只有你,所以如果配对的公钥解开了数据,就说明这数据是你发的,相反,则不是.这个被称为签名. 实际应用中,一般都是和对方交换公钥,然后你要发给对方的数据,用他的公钥加密,他得到后用他的私钥解密,他要发给你的数据,用你的公钥加密,你得到后用你的私钥解密,这样最大程度保证了安全性. RSA/DSA/SHA/MD5 非对称加密的算法有很多,比较著名的有RSA/DSA ,不同的是RSA可以用于加/解密,也可以用于签名验签,DSA则只能用于签名.至于SHA则是一种和md5相同的算法,它不是用于加密解密或者签名的,它被称为摘要算法.就是通过一种算法,依据数据内容生成一种固定长度的摘要,这串摘要值与原数据存在对应关系,就是原数据会生成这个摘要,但是,这个摘要是不能还原成原数据的,嗯....,正常情况下是这样的,这个算法起的作用就是,如果你把原数据修改一点点,那么生成的摘要都会不同,传输过程中把原数据给你再给你一个摘要,你把得到的原数据同样做一次摘要算法,与给你的摘要相比较就可以知道这个数据有没有在传输过程中被修改了. 实际应用过程中,因为需要加密的数据可能会很大,进行加密费时费力,所以一般都会把原数据先进行摘要,然后对这个摘要值进行加密,将原数据的明文和加密后的摘要值一起传给你.这样你解开加密后的摘要值,再和你得到的数据进行的摘要值对应一下就可以知道数据有没有被修改了,而且,因为私钥只有你有,只有你能解密摘要值,所以别人就算把原数据做了修改,然后生成一个假的摘要给你也是不行的,你这边用密钥也根本解不开. CA/PEM/DER/X509/PKCS 一般的公钥不会用明文传输给别人的,正常情况下都会生成一个文件,这个文件就是公钥文件,然后这个文件可以交给其他人用于加密,但是传输过程中如果有人恶意破坏,将你的公钥换成了他的公钥,然后得到公钥的一方加密数据,不是他就可以用他自己的密钥解密看到数据了吗,为了解决这个问题,需要一个公证方来做这个事,任何人都可以找它来确认公钥是谁发的.这就是CA,CA确认公钥的原理也很简单,它将它自己的公钥发布给所有人,然后一个想要发布自己公钥的人可以将自己的公钥和一些身份信息发给CA,CA用自己的密钥进行加密,这里也可以称为签名.然后这个包含了你的公钥和你的信息的文件就可以称为证书文件了.这样一来所有得到一些公钥文件的人,通过CA的公钥解密了文件,如果正常解密那么机密后里面的信息一定是真的,因为加密方只可能是CA,其他人没它的密钥啊.这样你解开公钥文件,看看里面的信息就知道这个是不是那个你需要用来加密的公钥了. 实际应用中,一般人都不会找CA去签名,因为那是收钱的,所以可以自己做一个自签名的证书文件,就是自己生成一对密钥,然后再用自己生成的另外一对密钥对这对密钥进行签名,这个只用于真正需要签名证书的人,普通的加密解密数据,直接用公钥和私钥来做就可以了. 密钥文件的格式用OpenSSL生成的就只有PEM和DER两种格式,PEM的是将密钥用base64编码表示出来的,直接打开你能看到一串的英文字母,DER格式是二进制的密钥文件,直接打开,你可以看到........你什么也看不懂!.X509是通用的证书文件格式定义.pkcs的一系列标准是指定的存放密钥的文件标准,你只要知道PEM DER X509 PKCS这几种格式是可以互相转化的. OpenSSL使用 PHP的OpenSSL模块要加载上很容易,百度一下,按着做就可以,但是这里面其实有很多问题,首先一点就是windows环境的问题,OpenSSL开发是以linux环境为基础的,现在开发者的windows下lamp集成环境会出现很多错误,如果你去OpenSSL官网可以看到它提供了专门的windows环境OpenSSL安装包.遗憾的是,没有提供给你PHP调用的解决办法,所以转了一圈我们又回到PHP自带的php_openssl.dll下了,你会发现在生成证书,提取公钥等等地方都会出现错误.我的解决办法是,在Apache的bin目录下用命令行来生成各种证书密钥,在PHP中只需要提取密钥做验证工作或者加密工作就可以了,密钥你只生成一次嘛,那个项目也不会需要你不停的变密钥对是吧.但是你要注意的是即使在Apache下使用命令行,你也需要一个特殊的openssl.cnf,这个可以用于windows环境,你可以百度一下,做了这些工作以后,你可以跟着我来生成各种密钥了,假设你在apache/bin目录下,所需要的exr,cnf,dll文件都拷贝到这个目录下了,然后你打开dos命令行,进入这个目录,做以下工作:
生成rsa密钥
openssl genrsa -des3 -out prikey.pem
去除掉密钥文件保护密码
openssl rsa -in prikey.pem -out prikey.pem
分离出公钥
openssl rsa -in prikey.pem -pubout -out pubkey.pem(获取证书中的公钥 openssl req -in myreq.pem -out -pubkey.pem)
对文件进行签名
open rsautl -sign -inkey prikey.pem -in a.txt -out sig.dat
验证签名
openssl rsautl -verify -inkey prikey.pem -in sig.dat
用公钥对文件加密
openssl rsautl -encrypt -pubin -inkey pubkey.pem -in a.text -out b.text
用私钥解密
openssl rsautl -decrypt -inkey prikey.pem -in b.text
用证书中的公钥加密
opensll rsautl -encrypt -certin -inkey cert1.pem -in a.txt
或者
生成一个没有加密的ca私钥
openssl genrsa -out ca.key.pem 1024
生成ca对应的csr文件
openssl req -new -key ca.key.pem -out ca.csr
自签名
openssl x509 -in ca.csr -out ca.cer -req -signkey ca.key.pem -days 7300 -extensions v3_ca
生成DER格式的私钥
openssl pkcs8 -topk8 -inform PEM -outform DER -in ca.key.pem -out ca.private.der -nocrypt
读取证书的内容,显示在屏幕上
openssl x509 -in server.cer -noout -subject -nameopt RFC2253
将der格式的证书转成pem格式
openssl x509 -inform PEM -outform DER -in server.der -out server.pem
如果那个命令提示你需要config文件,你在命令行的最后添加-config C:\wamp\bin\apache\apache2.2.8\conf\openssl.cnf,路径是你openssl.cnf的路径,根据你的cnf在哪里放设置. PHP中OpenSSL使用 提取公钥私钥
function get_pubkey($cert_file){
        $fp = fopen($cert_file, "r");
        $cert = fread($fp, 8192);
        fclose($fp);
        $pubkey = openssl_get_publickey($cert);
        $pubkeyid=$pubkey;
        openssl_free_key($pubkey);
        return $pubkeyid;
    }
     
function get_privkey($pri_file){
        $fp = fopen($pri_file, "rb");
        $priv_key = fread($fp, 8192);
        fclose($fp);
        $prikey = openssl_get_privatekey($priv_key,$password);
        $prikeyid=$prikey;
        openssl_free_key($prikey);
        return $prikeyid;
}
签名,验证签名
function sign_data($data,$priv_key){
        openssl_sign($data, $signature, $priv_key);
        $signature=base64_encode($signature);
        return $signature;
}
function verify_sign($data,$signature,$pubkeyid){
        $signature=base64_decode($signature);
        $ok = openssl_verify($data, $signature, $pubkeyid);
        if($ok==1){
            return $ok;
        }else{
            $sha1 = sha1($data, true);
            $sign = base64_decode($signature);
            $deco = '';
            openssl_public_decrypt($sign, $deco, $pubkeyid);
            if($sha1==$deco){
                $ok=1;
            }else{
                $ok=2;
            }
            return $ok;
        }
         
}
原文http://www.cnblogs.com/phpinfo/archive/2013/08/09/3246376.html