关于RSA密钥加密的一点想法

很久以前就有过这样的想法.

为什么:
1024比特的RSA 加密的数据不能超过117个字节(1024/8 – 11 = 117)
2048比特的RSA 加密的数据不能超过245个字节(2048/8 – 11 = 245)

后来看了一篇文章才恍然大悟RSA的主要作用是用来加密秘钥用的

比如AES加密的秘钥在传输过程为了避免被窃取,使用非对称RSA进行一次加密
后续的数据直接使用AES进行加密传输

当然RSA也可以对超长字节的数据进行加密,比如使用1024位的RSA密钥对超长数据进行加密
方法是:分割字符串每117(小于等于117)字节为一段,然后分段加密,最后连接到一起,
如果希望方便传输最后再来一次base64 encode

第三方账户登录的服务端验证组件xxtime/oauth-client

Oauth-client 用户第三方账户登录的服务端验证组件
支持 Google, Facebook, Weixin, Weibo 等.

我在公司的一些项目有所应用,还不错

安装

composer require xxtime/oauth-client dev-master

使用方法

$id = '{Google account id}';
$token = '{Google login account token}';
$option = [
    'clientId' => '{Google app id}'
];
try {
    $oauth = new OauthAdaptor('google', $option);
    $user = $oauth->verify($id, $token);
    print_r($user);
} catch (\Exception $e) {
    echo $e->getMessage();
}     

项目地址
https://github.com/xxtime/oauth-client

开源项目omnipay-mycard, 快速MyCard支付集成

项目地址 https://github.com/xxtime/omnipay-mycard

MyCard是台湾的一个电子支付服务商,类似于支付宝
但是MyCard的接入很烂,这是我见过所有支付集成平台最烂的接口
为了避免其他人在MyCard碰到各种坑,我就写了omnipay-mycard项目

omnipay-mycard项目是一个支付组件,使用composer就能很容易安装
目前稳定版本是 1.1.0

composer require "xxtime/omnipay-mycard:~1.1"

Omnipay是一个支持多网关支付的组件,也是The PHP League团队的旷世之作
由来自全球社区爱好者的精英们编写各个支付网关的适配器

目前国内的 支付宝 微信支付 银联支付 的适配器都囊括其中
不过支付宝的适配器写的不太规范 但用绝对没问题,我也跟其作者沟通,他希望有更多的人参与改进

好吧还是继续说omnipay-mycard吧
omnipay-mycard
支持 MyCard点卡支付,MyCard会员支付,MyCard电信类支付
支持MyCard对账

上代码吧:

// Initialize
$config = [
    'appId'  => 'MyCard_ServiceId',
    'appKey' => 'MyCard_Key'
];
$gateway = Omnipay::create('MyCard');
$gateway->initialize($config);

// Send purchase request
$response = $gateway->purchase(
    [
        'amount'        => '1.00',
        'currency'      => 'TWD',
        'description'   => 'product description',
        'transactionId' => mt_rand(100000, 999999),
    ]
)->send();

// Process response
if ($response->isRedirect()) {
    // doing something here
    // $token = $response->getToken();
    // $data = $response->getData();
    // $transactionReference = $response->getTransactionReference();
    $response->redirect();
}
elseif ($response->isSuccessful()) {
    // doing something here
    print_r($response);
}
else {
    echo $response->getMessage();
}

开源项目flysystem-aliyun-oss 阿里云OSS文件上传管理组件

项目地址 https://github.com/xxtime/flysystem-aliyun-oss

flysystem项目是 The PHP League 团队发起的用户文件上传管理等操作的项目
采用适配器的方式,支持本地文件操作,各种云操作,各种网盘,FTP,WebDAV 总之厉害了。

而我在发现没有阿里云的适配器的时候 就自己写了一个,并且已经收录到官方的适配器列表中,而且已有很多用户在使用

flysystem-aliyun-oss项目支持阿里云OSS系统的文件上传管理等操作

使用composer即可方便安装

使用方法见代码

use League\Flysystem\Filesystem;
use Xxtime\Flysystem\Aliyun\OssAdapter;

$filesystem = new Filesystem(new OssAdapter([
    'access_id'     => 'access_key_id',
    'access_secret' => 'access_key_secret',
    'bucket'        => 'bucket name',

    // 'endpoint'       => 'oss-cn-shanghai.aliyuncs.com',
    // 'timeout'        => 3600,
    // 'connectTimeout' => 10,
]));


// Write Files
$filesystem->write('path/to/file.txt', 'contents');

// Write Use writeStream
$stream = fopen('local/path/to/file.txt', 'r+');
$result = $filesystem->writeStream('path/to/file.txt', $stream);
if (is_resource($stream)) {
    fclose($stream);
}

// Update Files
$filesystem->update('path/to/file.txt', 'new contents');

// Check if a file exists
$exists = $filesystem->has('path/to/file.txt');

// Read Files
$contents = $filesystem->read('path/to/file.txt');

// Delete Files
$filesystem->delete('path/to/file.txt');

// Rename Files
$filesystem->rename('filename.txt', 'newname.txt');

// Copy Files
$filesystem->copy('filename.txt', 'duplicate.txt');


// list the contents (not support recursive now)
$filesystem->listContents('path', false);

官方项目
https://github.com/thephpleague/flysystem

开源项目Phalcon-Rest

最近我有写了一个开源项目Phalcon-Rest

Phalcon-Rest主要用来开发rest接口

项目地址  https://github.com/xxtime/phalcon-rest

特点:
使用phalcon构建的一个rest项目
高性能
支持composer
数据库支持MySql MongoDB Redis, 当然不限于此
事件监听机制
中间件功能
I18n多语言支持
调试工具whoops
各种神操作的路由写法

 

此项目的readme文档里还推荐了很多优秀的组件

PHP 加密算法 openssl_encrypt vs mcrypt_encrypt

$key = "anotherpassword1";
$str = "does it work 12";
$enc = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $str . "\1", MCRYPT_MODE_ECB);
$dec = mcrypt_decrypt(MCRYPT_BLOWFISH, $key, $enc, MCRYPT_MODE_ECB);
echo(bin2hex($enc) . PHP_EOL);
var_dump($dec);
$enc = openssl_encrypt($str, 'bf-ecb', $key, true);
$dec = openssl_decrypt($enc, 'bf-ecb', $key, true);
echo(bin2hex($enc) . PHP_EOL);
var_dump($dec);

实测结论:
1. mcrypt_encrypt的加密密钥超过56个字符串则报错
2. 当字符串$str的长度是len = (16*N)-1 时, mcrypt_decrypt 与 openssl_decrypt 可互相解密。(N取正整数)
3. openssl_decrypt加密过的数据可以用mcrypt_decrypt解密,不管$str长度是多少

引用http://php.net/manual/en/function.openssl-encrypt.php
http://php.net/manual/en/function.mcrypt-encrypt.php
http://php.net/manual/en/function.mcrypt-generic.php
http://stackoverflow.com/questions/9993909/php-replace-mcrypt-with-openssl

php与python在读取.ini配置文件时的区别,连词符&影响php读取配置

最近写程序时候发现一个问题
php 与 python 在读取 .ini 配置文件时候有一些区别

比如 在分别读取这三条配置的时候

password=123456
password=123&456
password=’123&456′

php 读取到的三个配置结果分别是:
123456
0
123&456

而python读取到的结果分别是:
123456
123&456
‘123&456’

由此可见
1.当配置的值中出现连词符&时,如果配置的值没有被引号包起来,则php会出错,读到的为0
2.php读取配置时,配置的值是否被引号包起来结果一样(上述的第一条除外)
3.python读取配置的时候所有等号后面的字符,包括引号,都认为是配置的值

nginx转发php请求到其他服务器

例如:服务器A转发php请求到服务器B

以下为A服务器修改

location ~ .php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}

修改下ip即可,改成PHP服务器的IP

location ~ .php$ {
fastcgi_pass 192.168.4.3:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}

以下为目标服务器配置(B服务器,即PHP服务器)

首先开启B服务器的端口 修改/etc/sysconfig/iptables增加一行
-A INPUT -m state --state NEW -m tcp -p tcp --dport 9000 -j ACCEPT

配置php-fpm文件
yum安装的通常在 /etc/php-fpm.d/www.conf,编译安装的通常在/usr/local/php/etc/php-fpm.conf

修改:
listen = 127.0.0.1:9000
改成
listen = 0.0.0.0:9000

修改
listen.allowed_clients = 127.0.0.1
添加允许的服务器,如本例中另外增加了两台服务器
listen.allowed_clients = 127.0.0.1,192.168.4.3,192.168.4.127
也可以注释掉 listen.allowed_clients 配置,因为默认允许任何机器连接,没有IP限制

注意: nginx服务器与php服务器两台的目录部署应该一致,否则会404错误找不到文件 “File not found.”

PHP 5.6.1编译安装,支持 Oracle MariaDB

大多数phper编译php的时候,的模式都很固定,简单的支持一些常见拓展 支持mysql就够了,而且这些phper们偏爱php5.2 php5.3 连php5.4都很少,很不愿意尝试编译新的版本,以后就固定用这个版本,用固定的编译代码。这样虽然很安全。但是我们应该开拓创新。

环境:Linux CentOS 7
PHP版本:php 5.6.1
目的:支持MariaDB(Mysql), Oracle数据库拓展 以及支持常用拓展组件

事先安装好了MariaDB,MariaDB跟Mysql差不多,此处不详细说明

先上段,尝试成功的编译代码(去掉oracle支持 去掉ldap支持)
./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --with-config-file-scan-dir=/usr/local/php/etc/php.d --with-mysql=/usr/local/mysql --with-mysqli=/usr/local/mysql/bin/mysql_config --with-pdo-mysql --with-iconv --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-libxml-dir=/usr --enable-xml --disable-rpath --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --enable-mbregex --enable-fpm --enable-mbstring --with-mcrypt --with-gd --enable-gd-native-ttf --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --with-openssl --enable-soap --enable-zip
然后拷贝php.ini到安装目录
把编译的目录下的 ./php-5.6.1/php.ini-production 拷贝到/usr/local/php/etc/php.ini

上面这段编译配置代码是在我尝试了很多次总结出来的,一去掉了一些编译配置(oracle 和 ldap配置),折腾了很久最终还是放弃在编译php过程中的oralce编译参数和ldap编译参数,如:
--with-oci8=shared,instantclient,/usr/local/lib64/oracle/client/lib --with-pdo-oci=instantclient,/usr/local/lib64/oracle/client/lib,12.1 --enable-opcache --with-ldap --with-ldap-sasl
其中–enable-opcache 没有尝试

PHP各版本说明:
PHP 5.5 开始增加 –enable-opcache参数,意思是启用Zend Opcache缓存功能,类似APC缓存
PHP 5.4 去掉了参数 –enable-safe-mode –enable-discard-path –enable-fastcgi –enable-force-cgi-redirect

但是Oracle,哥们儿我是要用的,怎么能少了你,继续折腾
执行 pecl install oci8 在需要录入的地方输入 shared,instantclient,/usr/local/lib64/oracle/client/lib
其中 /usr/local/lib64/oracle/client/lib 是在官网下载的几个oracle sdk

[root@joe-pc bin]# /usr/local/php/bin/pecl install oci8
downloading oci8-2.0.8.tgz ...
Starting to download oci8-2.0.8.tgz (190,854 bytes)
.........................................done: 190,854 bytes
11 source files, building
running: phpize
Configuring for:
PHP Api Version:         20131106
Zend Module Api No:      20131226
Zend Extension Api No:   220131226
Please provide the path to the ORACLE_HOME directory. Use 'instantclient,/path/to/instant/client/lib' if you're compiling with Oracle Instant Client [autodetect] : shared,instantclient,/usr/local/lib64/oracle/client/lib

在php配置文件里加入oracle支持
编辑 /usr/local/php/etc/php.d/oracle.ini 内容:

extension=oci8.so

启动 php-fpm,妈的报错
NOTICE: PHP message: PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/oci8.so' - libaio.so.1: cannot open shared object file: No such file or directory in Unknown on line 0
看来这oracle 还缺少libaio支持,也给装上

yum install libaio

然后kill掉php所有进程,重启 php-fpm

/usr/local/php/sbin/php-fpm

ok, 终于搞定了,生命在于折腾

php_error错误处理使用demo

DC9AE427-5699-47CE-9C29-8A85FF7686AA

官网地址:http://phperror.net/

<?php

//set the options in an array
$options = array(
          'snippet_num_lines' => 10,
          'background_text'  => 'xxtime',
          'display_line_numbers' => true
  );

//require the script and run the function passing the options ar argument
require('php_error.php');
php_errorreportErrors( $options );

//create a generic class with a private attribute
Class MyClass {
    private $name;
}

$class = new MyClass();
//try to set the value for the private attribute to generate an error
$class->name = "testing private attribute";