前幾日旅择,應(yīng)某數(shù)字貨幣交易網(wǎng)站(火幣網(wǎng))社區(qū)用戶請求泡挺,幫忙升級對應(yīng)的php sdk以適應(yīng)該平臺最新升級的加密驗(yàn)簽機(jī)制(因?yàn)榈谝粋€(gè)php api sdk也是我提供的,俗話說填坑填到底妻熊,送佛送到西畜眨。织阅。阶祭。)圆仔,就簡單研究了下基于php的橢圓加密曲線使用。
剛開始還疑惑了下扶叉,之前的密鑰驗(yàn)證已經(jīng)足夠安全勿锅,為何要引入橢圓簽名,再一想就立即明白了枣氧,普通的密鑰效驗(yàn)屬于對稱加密效驗(yàn)溢十,一旦官方服務(wù)器被攻克,所有安全效驗(yàn)都化為烏有达吞,而橢圓曲線的非對稱效驗(yàn)機(jī)制能保證在合理的架構(gòu)下张弛,黑客還需要拿到用戶的私鑰才能進(jìn)行攻擊,大大提升了安全性酪劫。近年來的非對稱效驗(yàn)api也有大幅上升趨勢吞鸭,諸多平臺已經(jīng)開始修改引入非對稱加密。
在我看來,非對稱加密有以下幾種特性
- 通過私鑰可以計(jì)算出公鑰滩字,但通過公鑰很難計(jì)算出私鑰
- 公鑰加密造虏,私鑰解密。主要適應(yīng)場景:不安全網(wǎng)絡(luò)下的數(shù)據(jù)交換行為麦箍,例如HTTPS瀏覽漓藕,金融系統(tǒng)
- 私鑰加密,公鑰解密挟裂。主要適應(yīng)場景:身份認(rèn)證享钞,代表你是該私鑰的所有人從而鑒定你的身份,目前大部分?jǐn)?shù)字貨幣的核心也是基于這個(gè)原理诀蓉。而該sdk中火幣所使用的驗(yàn)證方法也是該原理栗竖。
作為一只數(shù)字貨幣愛好狗,對加解密已經(jīng)有一定了解渠啤,不過對非對稱的原理還遠(yuǎn)不到手?jǐn)]類庫的地步(RSA算法研究了一半, 還沒研究完全)划滋,所以自然使用了第三方類庫來實(shí)現(xiàn)橢圓曲線效驗(yàn)。綜合考慮之后埃篓,選擇了github上的phpecc作為加密類庫处坪,考慮到兼容問題,使用了0.4版本(新版要求PHP7+)架专。
git clone git@github.com:phpecc/phpecc.git
cd phpecc
git reset --hard origin/0.4
composer install
// 或者直接引入
composer require mdanter/ecc:0.4.5
項(xiàng)目中直接加載vendor同窘,然后調(diào)用腳本引入phpecc命名空間
use Mdanter\Ecc\EccFactory;
use Mdanter\Ecc\Crypto\Signature\Signer;
use Mdanter\Ecc\Serializer\PrivateKey\PemPrivateKeySerializer;
use Mdanter\Ecc\Serializer\PrivateKey\DerPrivateKeySerializer;
use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer;
use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer;
use Mdanter\Ecc\Serializer\PublicKey\PemPublicKeySerializer;
初始化驗(yàn)簽類
$adapter = EccFactory::getAdapter();
$generator = EccFactory::getNistCurves()->generator384();
$useDerandomizedSignatures = true;
簽名生成過程第一步要先生成消息摘要,ecdsa使用sha256來生成
$algorithm = 'sha256';
$pemSerializer = new PemPrivateKeySerializer(new DerPrivateKeySerializer($adapter));
$key = $pemSerializer->parse(PRIVATE_KEY);
$signer = new Signer($adapter);
$hash = $signer->hashData($generator, $algorithm, $sig);
下一步部脚,隨機(jī)生成一個(gè)隨機(jī)大數(shù)randomk想邦,然后將上一步的消息摘要(也就是hash),私鑰和隨機(jī)數(shù)一起進(jìn)行簽名委刘,簽名過程是通過私鑰和隨機(jī)數(shù)計(jì)算出另2個(gè)大數(shù)r和s即可作為簽名丧没,第三方可用公鑰對r進(jìn)行驗(yàn)證計(jì)算s鹰椒,若s與簽名的s一致則驗(yàn)證通過。
$random = \Mdanter\Ecc\Random\RandomGeneratorFactory::getHmacRandomGenerator($key, $hash, $algorithm);
$randomK = $random->generate($generator->getOrder());
$signature = $signer->sign($key, $hash, $randomK);
$serializer = new DerSignatureSerializer();
$serializedSig = $serializer->serialize($signature);
return base64_encode($serializedSig);
注意randomk不是必須的呕童,但是加入隨機(jī)數(shù)會使安全性大幅提升漆际。
簽名完成后生成的簽名一般是二進(jìn)制流,可依據(jù)實(shí)際要求返回base64夺饲、hex或其他形式奸汇。
至此,非對稱校驗(yàn)就全部完成了往声,實(shí)際操作起來非常簡單擂找。不過內(nèi)部計(jì)算量卻并不小,經(jīng)反饋大部分語言都需要10-幾十毫秒的時(shí)間進(jìn)行簽名浩销,要知道量化交易拼的就是那么幾毫秒甚至0.x毫秒贯涎,所以引入非對稱之后很多人都表示需要升級配置來適應(yīng)系統(tǒng)了。
網(wǎng)友對該升級的意見: