GnuPG简介
GnuPG 是 RFC4880 OpenPGP 标准 PGP 的完整实现,自由软件。GnuPG 可以加密和签名数据和信息传递,包含一个通用的密钥管理系统,包含的访问模块可以访问各种公钥目录。 GnuPG, 简称 GPG, 是命令行工具,很方便和其它程序进行整合,具有很多前端程序和函数库。 GnuPG V2 还支持 S/MIME 和 Secure Shell (ssh). 更多详细介绍点击这里
安装PHP GnuPG扩展
目前该扩展没有找到windows版本,是在linux系统centos7安装测试的
解压扩展包
tar xvf gnupg-1.4.0.tgz
进入扩展目录进行安装操作
cd gnupg-1.4.0
/www/server/php/72/bin/phpize //用自己的phpize路径
./configure --with-php-config=/www/server/php/72/bin/php-config //用自己的php-config路径
make && make install
echo "extension = gnupg.so" >> /www/server/php/72/etc/php.ini //用自己的php.ini路径
如果checkconfig时报错please reinstall the gpgme distribution(请重新安装gpgme发行版),如下图
如出现这种错误我们需要安装下gpgme,直接执行命令 yum install gpgme-devel安装即可!
验证扩展是否安装成功:在页面打印出phpinfo,搜索gnupg,搜到说明安装成功!
创建GPG密钥
网上有很多教程可以参考这里,这里主要说下遇见的问题:
生成密钥最后一步不要设置保护密码,因为高版本的gpg密码无法通过普通的程序传输,会导致解密失败。
生成密钥过程中如果卡住了,说明机器没有生成足够的随机数,需要安装rngd服务---熵值,命令如下
yum -y install rng-tools
rngd -r /dev/urandom
Web服务器开通访问权限
cd /root/.gnupg
chown: www pubring.gpg trustdb.gpg secring.gpg
chmod 660 pubring.gpg trustdb.gpg secring.gpg
复制代码
PHP通过GPG加密解密
/**
* 公钥加密
* @param $text
* @param $publicKey
* @return mixed
*/
public function encrypt($text, $publicKey)
{
try{
$gpg = gnupg_init();
gnupg_seterrormode($gpg, GNUPG_ERROR_EXCEPTION);
$keyInfo = gnupg_import($gpg, file_get_contents($publicKey));//导入公钥
gnupg_addencryptkey($gpg, $keyInfo['fingerprint']);
$encryptText = gnupg_encrypt($gpg, $text);
if ($encryptText !== false) {
$ret['code'] = 1;
$ret['msg'] = '加密成功!';
$ret['encryptText'] = $encryptText;
} else {
$ret['code'] = -10001;
$ret['msg'] = '加密失败!';
}
} catch (\Exception $e) {
$ret['code'] = -10002;
$ret['msg'] = 'ERROR: ' . $e->getMessage();
}
return $ret;
}
/**
* 私钥解密
* @param $text
* @param $privateKey
* @return mixed
*/
public function decrypt($text, $privateKey)
{
try {
$gpg = gnupg_init();
gnupg_seterrormode($gpg, GNUPG_ERROR_EXCEPTION);
$keyInfo = gnupg_import($gpg, file_get_contents($privateKey));//导入私钥
gnupg_adddecryptkey($gpg, $keyInfo['fingerprint']);
$decryptText = gnupg_decrypt($gpg, $text);
if ($decryptText !== false) {
$ret['code'] = 1;
$ret['msg'] = '解密成功!';
$ret['decryptText'] = $decryptText;
} else {
$ret['code'] = -10001;
$ret['msg'] = '解密失败!';
}
} catch (\Exception $e) {
$ret['code'] = -10002;
$ret['msg'] = 'ERROR: ' . $e->getMessage();
}
return $ret;
}
/**
* 签名加密
* @param $text
* @param $signKey
* @param $EncryptKey
* @return mixed
*/
public function signEncrypt($text, $signKey, $EncryptKey)
{
try {
$gpg = gnupg_init();
gnupg_seterrormode($gpg, GNUPG_ERROR_EXCEPTION);
$signKeyInfo = gnupg_import($gpg, file_get_contents($signKey));//导入密钥
$EncryptKeyInfo = gnupg_import($gpg, file_get_contents($EncryptKey));//导入密钥
gnupg_addsignkey($gpg, $signKeyInfo['fingerprint']);
gnupg_addencryptkey($gpg, $EncryptKeyInfo['fingerprint']);
$signEncryptText = gnupg_encryptsign($gpg, $text);
if ($signEncryptText !== false) {
$ret['code'] = 1;
$ret['msg'] = '签名加密成功!';
$ret['signEncryptText'] = $signEncryptText;
} else {
$ret['code'] = -10001;
$ret['msg'] = '签名加密失败!';
}
} catch (\Exception $e) {
$ret['code'] = -10002;
$ret['msg'] = 'ERROR: ' . $e->getMessage();
}
return $ret;
}
/**
* 私钥签名
* @param $text
* @param $privateKey
* @return mixed
*/
public function sign($text, $privateKey)
{
try {
$gpg = gnupg_init();
gnupg_seterrormode($gpg, GNUPG_ERROR_EXCEPTION);
$keyInfo = gnupg_import($gpg, file_get_contents($privateKey));//导入私钥
gnupg_addsignkey($gpg, $keyInfo['fingerprint']);
$signText = gnupg_sign($gpg, $text);
if ($signText !== false) {
$ret['code'] = 1;
$ret['msg'] = '签名成功!';
$ret['signText'] = $signText;
} else {
$ret['code'] = -10001;
$ret['msg'] = '签名失败!';
}
} catch (\Exception $e) {
$ret['code'] = -10002;
$ret['msg'] = 'ERROR: ' . $e->getMessage();
}
return $ret;
}
/**
* 验签
* @param $signText
* @return mixed
*/
public function verify($signText)
{
try {
$gpg = gnupg_init();
gnupg_seterrormode($gpg, GNUPG_ERROR_EXCEPTION);
$text = '';
$verifyInfo = gnupg_verify($gpg, $signText, false, $text);
$res = gnupg_keyinfo($gpg, $verifyInfo['fingerprint']);
if ($res !== false) {
$ret['code'] = 1;
$ret['msg'] = '验签成功!';
$ret['verifyText'] = $text;
} else {
$ret['code'] = -10001;
$ret['msg'] = '验签失败!';
}
} catch (\Exception $e) {
$ret['code'] = -10002;
$ret['msg'] = 'ERROR: ' . $e->getMessage();
}
return $ret;
}
复制代码