非對稱加密openssl協議在php7實踐

  • 2019 年 10 月 3 日
  • 筆記

      據網上資料,RSA加密演算法是一種非對稱加密演算法。在公開密鑰加密和電子商務中RSA被廣泛使用。RSA是1977年由羅納德·李維斯特(RON RIVEST)、阿迪·薩莫爾(ADI SHAMIR)和倫納德·阿德曼(LEONARD ADLEMAN)一起提出的。當時他們三人都在麻省理工學院工作。RSA就是他們三人姓氏開頭字母拼在一起組成的。

    工作中經常會出現對敏感數據加解密的需要,比如自己當前金融公司涉及到的用戶交易數據,用戶身份識別驗證等。這裡有關用戶身份識別的用到了RSA加密演算法。php這裡用到了openss協議。

    非對稱加密即是私鑰加密需用公鑰解密;公鑰加密的需用私鑰解密;公鑰和私鑰是成對出現,公鑰可以派發給所用人,私鑰只可服務端保留。

    下面是php實現的openssl加解密部分示例程式碼:

##伺服器是centos7
##首先確定伺服器是否安裝openssl協議(未安裝的請執行命令yum install -y openssl-devel): [root@iz2vcf47jzvf8dxrapolf7z test]# openssl version OpenSSL
1.0.2k-fips 26 Jan 2017 [root@iz2vcf47jzvf8dxrapolf7z test]# #生成私鑰文件rsa_private_key.pem文件 [root@iz2vcf47jzvf8dxrapolf7z test]# openssl genrsa -out rsa_private_key.pem 1024 Generating RSA private key, 1024 bit long modulus ..................................................++++++ ........................................................................++++++ e is 65537 (0x10001)
##私鑰轉成pkcs8模式(文末附各模式說明)
[root@iz2vcf47jzvf8dxrapolf7z test]# openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem
##列印私鑰文件 [root@iz2vcf47jzvf8dxrapolf7z test]#
cat rsa_private_key.pem -----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQCh13gUKZWQlx7cuYQvY1A6JuJjArMax8yHcTrtcL+kpa5Cg6mD 609QNiTacuJxmh7Q/w+1Lw/cuWN0Q7s3s4WzJET6YCi3fH4zqVmpqWIcKWC/hE3p VV3lJsBvMpoz2bFn1eRwVtmSp4dVAqe542YvbZ13VGheEvkKi5uqWyhY1wIDAQAB AoGAIYSjjOFz5Wc28BXH55yU8AY/mqvjdidtF5v+zVAtkKbzqTjlcbnZSk58YXWr qkV2HmjE0wx1J4yJqXmhm46loLkIpWdQfzRyFFnK3xmo9Lc6jXbIrKmFYyN7FTqT 5cADvrTJ2jO9BlDG0ddTp7pl6dRi00jkrTRU3mgxZZ1kOWkCQQDRZZl9LKs+lz0v kOEKGuhjfHpFYpjce/mg0XfOZuFIqYXdm/nO1nx/KAr+xtUhiqkRzdxADOA0Nrxg alCtT1NbAkEAxdxotvcFYKOFES1aOAg35mv7Inlnjelbj1Jx0wtGRVUV/0nvMVKf TLInECD2mUaE00OWjuXanAI2FQQWbML1NQJBAL/AGDRGaXJhsIgUVd+ZEGG6JYXQ akbNyKR57Qo3r+mIQ6vSH4pHY65VjuwMTDPw9C33o8+LeuyVix+He+WZFK0CQQDA Gb+9LFYXPou6Yqr+TdRgLiSUkwScfp27qBMFESQ3umVyB8lovMwXPby5ZxelNxdM uolZ0gaOg4MYonBXRm2lAkAEOjH32XMSTB+HI+lQrLCFiumyRjHpgbRgTcyUQolY fjR63M0E/rzVIneKPqLP+ySOYLFcO3bjuMa75CQic8PF -----END RSA PRIVATE KEY-----


 ##根據私鑰得到相應的公鑰
 [root@iz2vcf47jzvf8dxrapolf7z test]# openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
 writing RSA key
 [root@iz2vcf47jzvf8dxrapolf7z test]# cat rsa_public_key.pem
 —–BEGIN PUBLIC KEY—–
 MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCh13gUKZWQlx7cuYQvY1A6JuJj
 ArMax8yHcTrtcL+kpa5Cg6mD609QNiTacuJxmh7Q/w+1Lw/cuWN0Q7s3s4WzJET6
 YCi3fH4zqVmpqWIcKWC/hE3pVV3lJsBvMpoz2bFn1eRwVtmSp4dVAqe542YvbZ13
 VGheEvkKi5uqWyhY1wIDAQAB
 —–END PUBLIC KEY—–

##新建openssl.php
[root@iz2vcf47jzvf8dxrapolf7z test]# cat openssl.php

<?
/**
 * 私鑰加密/公鑰解密
 *
 * @param $str string 待加解密字元串
 * @param $isEncrypt boolean
 * return string|null
 */
 function opensslPrivateEncrypt($str, $isEncrypt = true)
 {

  if($isEncrypt){
    $privateKey = file_get_contents(‘./rsa_private_key.pem’);
    $privateKey = openssl_pkey_get_private($privateKey);

    return openssl_private_encrypt($str, $encryptedStr, $privateKey)
      ? base64_encode($encryptedStr) : null;
  }else{
    $publicKey = file_get_contents(‘./rsa_public_key.pem’);
    $publicKey = openssl_pkey_get_public($publicKey);

    return (openssl_public_decrypt(base64_decode($str), $decryptedStr, $publicKey))
    ? $decryptedStr : null;
  }
}

/**
 * 公鑰加密/私鑰解密
 *
 * @param $str string 待加解密字元串
 * @param $isEncrypt boolean
 * return string|null
 */
function opensslPublicEncrypt($str , $isEncrypt = true)
{

  if($isEncrypt){
    $publicKey = file_get_contents(‘./rsa_public_key.pem’);
    $publicKey = openssl_pkey_get_public($publicKey);

    return openssl_public_encrypt($str, $encryptedStr, $publicKey)
      ? base64_encode($encryptedStr) : null;
  }else{
    $privateKey = file_get_contents(‘./rsa_private_key.pem’);
    $privateKey = openssl_pkey_get_private($privateKey);

    return (openssl_private_decrypt(base64_decode($str), $decryptedStr, $privateKey))
      ? $decryptedStr : null;
  }
}

$config = array();
$config[‘title’] = ‘PHP is the best program language.’;
$config[‘comment’] = ‘PHPERS are great people.’;

$privateEncrypt = opensslPrivateEncrypt(json_encode($config));
echo(“##privateEncrypt is:” . PHP_EOL);
echo($privateEncrypt . PHP_EOL);
$privateDecrypt = opensslPrivateEncrypt($privateEncrypt, false);
echo(“##privateDecrypt is:” . PHP_EOL);
echo($privateDecrypt . PHP_EOL);

$publicEncrypt = opensslPublicEncrypt(json_encode($config));
echo(“##publicEncrypt is:” . PHP_EOL);
echo($publicEncrypt . PHP_EOL);
$publicDecrypt = opensslPublicEncrypt($publicEncrypt, false);
echo(“##publicDecrypt is:” . PHP_EOL);
echo($publicDecrypt . PHP_EOL);

##執行腳本
[root@iz2vcf47jzvf8dxrapolf7z test]# php openssl.php

##privateEncrypt is:
mLrLIAwbwlE69Yj5/lnNw1t8qSjhnFa+96s/kSMYweAn/HEsV7jfVAJ6mn/FY2DRRWkKeOnguUYsRcFTBcS1ieG7UtqbUAASXA5dwVgtTrFoDcDhHMl7p90+dIO8n+vMoBx1kkUegpvtH03y3MgUVSj/BLkLE8jrFXyjGufIcv0=
##privateDecrypt is:
{“title”:”PHP is the best program language.”,”comment”:”PHPERS are great people.”}
##publicEncrypt is:
NW2k5m2pKrZmEMSHXiK7mfyC+yDjH1+b6TrEMPv+ywBfsUlo2P8eWwcXOQxvsV4UG87a1S4Xa2QySntdEwhpYoim97457ODVVCb6jx+cqqdWJ1wlLS+gx7FJxw7Z0kMPmCm5iMcQwWPK+UzF+dpc/gJFa9uGAAmYczUumOauAx0=
##publicDecrypt is:
{“title”:”PHP is the best program language.”,”comment”:”PHPERS are great people.”}

pkcs標準:

PKCS標準匯總
  版本 名稱 簡介
PKCS #1 2.1 RSA密碼編譯標準(RSA Cryptography Standard) 定義了RSA的數理基礎、公/私鑰格式,以及加/解密、簽/驗章的流程。1.5版本曾經遭到攻擊。
PKCS #2 撤銷 原本是用以規範RSA加密摘要的轉換方式,現已被納入PKCS#1之中。
PKCS #3 1.4 DH密鑰協議標準(Diffie-Hellman key agreement Standard) 規範以DH密鑰協議為基礎的密鑰協議標準。其功能,可以讓兩方通過金議協議,擬定一把會議密鑰(Session key)。
PKCS #4 撤銷 原本用以規範轉換RSA密鑰的流程。已被納入PKCS#1之中。
PKCS #5 2.0 密碼基植加密標準(Password-based Encryption Standard) 參見RFC 2898與PBKDF2
PKCS #6 1.5 證書擴展語法標準(Extended-Certificate Syntax Standard) 將原本X.509的證書格式標準加以擴充。
PKCS #7 1.5 密碼消息語法標準(Cryptographic Message Syntax Standard) 參見RFC 2315。規範了以公開密鑰基礎設施(PKI)所產生之簽名/密文之格式。其目的一樣是為了拓展數字證書的應用。其中,包含了S/MIMECMS
PKCS #8 1.2 私鑰消息表示標準(Private-Key Information Syntax Standard). Apache讀取證書私鑰的標準。
PKCS #9 2.0 選擇屬性格式(Selected Attribute Types) 定義PKCS#6、7、8、10的選擇屬性格式。
PKCS #10 1.7 證書申請標準(Certification Request Standard) 參見RFC 2986。規範了向證書中心申請證書之CSR(certificate signing request)的格式。
PKCS #11 2.20 密碼設備標準介面(Cryptographic Token Interface (Cryptoki)) 定義了密碼設備的應用程式介面(API)之規格。
PKCS #12 1.0 個人消息交換標準(Personal Information Exchange Syntax Standard) 定義了包含私鑰與公鑰證書(public key certificate)的文件格式。私鑰采密碼(password)保護。常見的PFX就履行了PKCS#12。
PKCS #13 橢圓曲線密碼學標準(Elliptic curve cryptography Standard) 制定中。規範以橢圓曲線密碼學為基礎所發展之密碼技術應用。橢圓曲線密碼學是新的密碼學技術,其強度與效率皆比現行以指數運算為基礎之密碼學演算法來的優秀。然而,該演算法的應用尚不普及。
PKCS #14 擬隨機數產生器標準(Pseudo-random Number Generation) 制定中。規範擬隨機數產生器的使用與設計。
PKCS #15 1.1 密碼設備消息格式標準(Cryptographic Token Information Format Standard) 定義了密碼設備內部數據的組織結構。