PHP的學習--RSA加密解密

PHP服務端與客戶端交互或者提供開放API時,一般須要對敏感的數據進行加密,這時候rsa非對稱加密就能派上用處了。javascript

舉個通俗易懂的例子,假設咱們再登陸一個網站,發送帳號和密碼,請求被攔截了。php

  • 密碼沒加密,那***者就直接拿到了密碼,這是最搓的。html

  • 密碼加密了,是不可逆加密,那***者只須要模擬那個請求便可登陸。前端

  • 密碼加密了,是可逆加密,其中攜帶有時間等參數,後臺能夠根據時間等參數來判斷是否有效,但由於是在前端加密,其加密方式也能在代碼中找到,找到加密方式就能夠得出解密方式。java

可是若是咱們使用非對稱加密就能夠避免以上問題。jquery

非對稱加密算法須要兩個密鑰來進行加密和解密,這兩個祕鑰是公開密鑰(public key,簡稱公鑰)和私有密鑰(private key,簡稱私鑰)。git

工做過程以下,甲乙之間使用非對稱加密的方式完成了重要信息的安全傳輸。github

非對稱加密工做過程簡要示意圖

  • 乙方生成一對密鑰(公鑰和私鑰)並將公鑰向其它方公開。算法

  • 獲得該公鑰的甲方使用該密鑰對機密信息進行加密後再發送給乙方。後端

  • 乙方再用本身保存的另外一把專用密鑰(私鑰)對加密後的信息進行解密。乙方只能用其專用密鑰(私鑰)解密由對應的公鑰加密後的信息。

在傳輸過程當中,即便***者截獲了傳輸的密文,並獲得了乙的公鑰,也沒法破解密文,由於只有乙的私鑰才能解密密文。
一樣,若是乙要回復加密信息給甲,那麼須要甲先公佈甲的公鑰給乙用於加密,甲本身保存甲的私鑰用於解密。

在非對稱加密中使用的主要算法有:RSA、Elgamal、揹包算法、Rabin、D-H、ECC(橢圓曲線加密算法)等。

下面咱們經過一個例子來講明如何用PHP來實現RSA的加密解密。

<?phpclass Rsa{    public $privateKey = '';

    public $publicKey = '';
    
    public function __construct()
    {        $resource = openssl_pkey_new();
        openssl_pkey_export($resource, $this->privateKey);
        $detail = openssl_pkey_get_details($resource);
        $this->publicKey = $detail['key'];
    }    public function publicEncrypt($data, $publicKey)
    {        openssl_public_encrypt($data, $encrypted, $publicKey);
        return $encrypted;
    }    public function publicDecrypt($data, $publicKey)
    {        openssl_public_decrypt($data, $decrypted, $publicKey);
        return $decrypted;
    }    public function privateEncrypt($data, $privateKey)
    {        openssl_private_encrypt($data, $encrypted, $privateKey);
        return $encrypted;
    }    public function privateDecrypt($data, $privateKey)
    {        openssl_private_decrypt($data, $decrypted, $privateKey);
        return $decrypted;
    }
}$rsa = new Rsa();echo "公鑰:\n", $rsa->publicKey, "\n";echo "私鑰:\n", $rsa->privateKey, "\n";// 使用公鑰加密$str = $rsa->publicEncrypt('hello', $rsa->publicKey);// 這裏使用base64是爲了避免出現亂碼,默認加密出來的值有亂碼$str = base64_encode($str);echo "公鑰加密(base64處理過):\n", $str, "\n";$str = base64_decode($str);$pubstr = $rsa->publicDecrypt($str, $rsa->publicKey);echo "公鑰解密:\n", $pubstr, "\n";$privstr = $rsa->privateDecrypt($str, $rsa->privateKey);echo "私鑰解密:\n", $privstr, "\n";// 使用私鑰加密$str = $rsa->privateEncrypt('world', $rsa->privateKey);// 這裏使用base64是爲了避免出現亂碼,默認加密出來的值有亂碼$str = base64_encode($str);echo "私鑰加密(base64處理過):\n", $str, "\n";$str = base64_decode($str);$pubstr = $rsa->publicDecrypt($str, $rsa->publicKey);echo "公鑰解密:\n", $pubstr, "\n";$privstr = $rsa->privateDecrypt($str, $rsa->privateKey);echo "私鑰解密:\n", $privstr, "\n";

你們執行一下能夠看到公鑰加密的數據,只有私鑰能解密,反之亦然,私鑰加密的數據只有公鑰能解碼。

執行結果以下:

587057-20170102150515909-561221166.png

這是PHP端的實現,可用在第三方跟平臺之間的數據傳輸,但若是是前端傳到後端該怎麼辦呢,搜索了一下,發現了這個庫jsencrypt

使用jsencrypt加密解密的例子以下:

<!DOCTYPE html><html><head>
  <title>JSEncrypt Example</title>
  <base id="basetag" href="/jsencrypt-2.3.0/">
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="jquery.js"></script>
  <script type="text/javascript" src="bin/jsencrypt.js"></script></head><body><div class="container">
  <script type="text/javascript">

  // Call this code when the page is done loading.
  $(function() {

    // Run a quick encryption/decryption when they click.
    $('#testme').click(function() {

      // Encrypt with the public key...
      var encrypt = new JSEncrypt();
      encrypt.setPublicKey($('#pubkey').val());
      var encrypted = encrypt.encrypt($('#input').val());
      console.log(encrypted)      // Decrypt with the private key...
      var decrypt = new JSEncrypt();
      decrypt.setPrivateKey($('#privkey').val());
      var uncrypted = decrypt.decrypt(encrypted);
      console.log(uncrypted)      // Now a simple check to see if the round-trip worked.
      if (uncrypted == $('#input').val()) {
        alert('It works!!!');
      } else {
        alert('Something went wrong....');
      }
    });
  });</script><label for="privkey">Private Key</label><br/><textarea id="privkey" rows="15" cols="65">-----BEGIN PRIVATE KEY-----MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDkaTKbAERvJGE0
jGsdPXUI1FpO1uDkBkuuQU4LRv0Quw9r8j+fVNkN9rZVXMV7MiGOgb80Z0k9zRxZ
5KWOqMnSlrpyO3WjhFpDJeSmqZ4wLMFwmxrr31AjabD5Nkf9dQ7RiEIuM49g27+M
3OFvdIPcLgCyXnkl8FwBceBs38QbCXY5MrwlZr13yWZnyj6fbbG8t4atAzJ6bnj3
FZuvynC3QnMaVi6YnTIlBOUOHtqt/jsUTOCWkwKqkZh+RZF2fx3IFkSpJAOMgT5p
jSnfEJkK5E4JJHobLo/dFO0J7Gve+qb/lfJ9UpnZe78N1TAvbJiNZoN22ghbuIAW
M5qqIqOzAgMBAAECggEBAItUJFtqoVQOpADy+s/+UirNpjzbVJmjwXyNN3cnmW0g
PjsBrY+aqUCcUwLlMU2B+fg86w6jRokdWgL3t4m7Kkl8SkUuQgc5z/mP3tdPNkB6
vJDc/GIPeYnwidSrKOTSB/UGoiAesYJK6aCaiCV9tIWVxjUH7eyXnvf+qAChyrUW
PG/FirLyYmz1yRG99VKKE+iEIzemGSswU0DI0bwTFQ0MunLeJf0EdT20XppNwnl4
uoRgOBpMkW02vxDDWke2YIpk128KFRtPE3zF7W+Prb3ifMuQHSqDdqTgZA5+G3A9
D+lwczy95+0mIBpJ8rKQGjJ51ZT5WVMET9+Hb9+nUIECgYEA9NluRzIi9tZxwQa2
KdU8WAtWZZQZfG18mSFg8/QYrAGF2TyLAW0mEIe7nQXxPzm50HdpxTJCkUrXGm3u
hfPayx18H4oVVYRepSSfV+xe7wdogJWV6i5h/LaZsiTk1O8vF9Cwc3yUyVoMtKsg
yVcsONOzo/Kg/vwejQJb1C8dNvMCgYEA7tAewjA25vDmfiWZ0lrWKlwGQZ97+pMU
X+N12DWxL1Lvi6jBKXlK+Eiz19Qm/mBz9RxrDDY4/o0IjtTxdOh5thDaiqIcnqQn
PiBpm7zbheZOlPBGjFJ1vwueIWvqbx9vcqHik/4xHwuFNwQ+YCSpVpVoqrgoN/h/
fX5+hKm1kEECgYEAzn69UZAICtLKNveZE+jBLqPJJnvjjpur1F1hLfzz/cR/BLnZ
pcdOrew7Hu+PCTp+6kB7VJLRr0VF6gVCf3gsUta4AsVqvqeXRoF/XSB84+wEh0Ug
nNKnUwEQ2DvjPW3G8rfOyGcN+E5YntogGY3KPtbUDvWmL8WjYlrV5Toi0l8CgYAQ
Ujr37JGkAOzPzEQSA1FFvdpTm9G+U1T+JK6GI01DvbhPZC4nZnnAND/OTVqI4hCq
vNF4GTCV/Q+Lq3QBGG5RCh/Vf7TTBscD0PVGxoZ+RTozpaQ8rNoNP38EK7ru80gL
npK8qI+03nWxR+H3cin8l+N6X3GoOZyE+CMvb+XPwQKBgEeDjwTWxVhH/uksO3pw
MgbHjauD6AjuW9jc2a7ngFCWSQxQ3+xK1Spn6pbVdLPiBgInxCIl8d6S1yFU0Uan
iZHgy4fs1hdJRSuJ6qydqSwlS2C+gDpyY8ye0i+jq5VYYhKcpJCrCgaQGbleuaUd
ldp7v1FD8uyeemknGA35f6Id-----END PRIVATE KEY-----</textarea><br/><label for="pubkey">Public Key</label><br/><textarea id="pubkey" rows="15" cols="65">-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5GkymwBEbyRhNIxrHT11
CNRaTtbg5AZLrkFOC0b9ELsPa/I/n1TZDfa2VVzFezIhjoG/NGdJPc0cWeSljqjJ
0pa6cjt1o4RaQyXkpqmeMCzBcJsa699QI2mw+TZH/XUO0YhCLjOPYNu/jNzhb3SD
3C4Asl55JfBcAXHgbN/EGwl2OTK8JWa9d8lmZ8o+n22xvLeGrQMyem549xWbr8pw
t0JzGlYumJ0yJQTlDh7arf47FEzglpMCqpGYfkWRdn8dyBZEqSQDjIE+aY0p3xCZ
CuROCSR6Gy6P3RTtCexr3vqm/5XyfVKZ2Xu/DdUwL2yYjWaDdtoIW7iAFjOaqiKj
swIDAQAB-----END PUBLIC KEY-----</textarea><br/><label for="input">Text to encrypt:</label><br/><textarea id="input" name="input" type="text" rows=4 cols=70>This is a test!</textarea><br/><input id="testme" type="button" value="Test Me!!!" /><br/></div></body></html>

其中的公鑰和私鑰都是上面PHP代碼中生成的,這邊好像只有公鑰加密,私鑰解密。

拿到其中打印出的加密後的數據,嘗試在PHP中進行解密,能夠看到也能解密成功。代碼以下:

<?phpclass Rsa{    public $privateKey = '-----BEGIN PRIVATE KEY-----MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDkaTKbAERvJGE0jGsdPXUI1FpO1uDkBkuuQU4LRv0Quw9r8j+fVNkN9rZVXMV7MiGOgb80Z0k9zRxZ5KWOqMnSlrpyO3WjhFpDJeSmqZ4wLMFwmxrr31AjabD5Nkf9dQ7RiEIuM49g27+M3OFvdIPcLgCyXnkl8FwBceBs38QbCXY5MrwlZr13yWZnyj6fbbG8t4atAzJ6bnj3FZuvynC3QnMaVi6YnTIlBOUOHtqt/jsUTOCWkwKqkZh+RZF2fx3IFkSpJAOMgT5pjSnfEJkK5E4JJHobLo/dFO0J7Gve+qb/lfJ9UpnZe78N1TAvbJiNZoN22ghbuIAWM5qqIqOzAgMBAAECggEBAItUJFtqoVQOpADy+s/+UirNpjzbVJmjwXyNN3cnmW0gPjsBrY+aqUCcUwLlMU2B+fg86w6jRokdWgL3t4m7Kkl8SkUuQgc5z/mP3tdPNkB6vJDc/GIPeYnwidSrKOTSB/UGoiAesYJK6aCaiCV9tIWVxjUH7eyXnvf+qAChyrUWPG/FirLyYmz1yRG99VKKE+iEIzemGSswU0DI0bwTFQ0MunLeJf0EdT20XppNwnl4uoRgOBpMkW02vxDDWke2YIpk128KFRtPE3zF7W+Prb3ifMuQHSqDdqTgZA5+G3A9D+lwczy95+0mIBpJ8rKQGjJ51ZT5WVMET9+Hb9+nUIECgYEA9NluRzIi9tZxwQa2KdU8WAtWZZQZfG18mSFg8/QYrAGF2TyLAW0mEIe7nQXxPzm50HdpxTJCkUrXGm3uhfPayx18H4oVVYRepSSfV+xe7wdogJWV6i5h/LaZsiTk1O8vF9Cwc3yUyVoMtKsgyVcsONOzo/Kg/vwejQJb1C8dNvMCgYEA7tAewjA25vDmfiWZ0lrWKlwGQZ97+pMUX+N12DWxL1Lvi6jBKXlK+Eiz19Qm/mBz9RxrDDY4/o0IjtTxdOh5thDaiqIcnqQnPiBpm7zbheZOlPBGjFJ1vwueIWvqbx9vcqHik/4xHwuFNwQ+YCSpVpVoqrgoN/h/fX5+hKm1kEECgYEAzn69UZAICtLKNveZE+jBLqPJJnvjjpur1F1hLfzz/cR/BLnZpcdOrew7Hu+PCTp+6kB7VJLRr0VF6gVCf3gsUta4AsVqvqeXRoF/XSB84+wEh0UgnNKnUwEQ2DvjPW3G8rfOyGcN+E5YntogGY3KPtbUDvWmL8WjYlrV5Toi0l8CgYAQUjr37JGkAOzPzEQSA1FFvdpTm9G+U1T+JK6GI01DvbhPZC4nZnnAND/OTVqI4hCqvNF4GTCV/Q+Lq3QBGG5RCh/Vf7TTBscD0PVGxoZ+RTozpaQ8rNoNP38EK7ru80gLnpK8qI+03nWxR+H3cin8l+N6X3GoOZyE+CMvb+XPwQKBgEeDjwTWxVhH/uksO3pwMgbHjauD6AjuW9jc2a7ngFCWSQxQ3+xK1Spn6pbVdLPiBgInxCIl8d6S1yFU0UaniZHgy4fs1hdJRSuJ6qydqSwlS2C+gDpyY8ye0i+jq5VYYhKcpJCrCgaQGbleuaUdldp7v1FD8uyeemknGA35f6Id-----END PRIVATE KEY-----';

    public $publicKey = '-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5GkymwBEbyRhNIxrHT11CNRaTtbg5AZLrkFOC0b9ELsPa/I/n1TZDfa2VVzFezIhjoG/NGdJPc0cWeSljqjJ0pa6cjt1o4RaQyXkpqmeMCzBcJsa699QI2mw+TZH/XUO0YhCLjOPYNu/jNzhb3SD3C4Asl55JfBcAXHgbN/EGwl2OTK8JWa9d8lmZ8o+n22xvLeGrQMyem549xWbr8pwt0JzGlYumJ0yJQTlDh7arf47FEzglpMCqpGYfkWRdn8dyBZEqSQDjIE+aY0p3xCZCuROCSR6Gy6P3RTtCexr3vqm/5XyfVKZ2Xu/DdUwL2yYjWaDdtoIW7iAFjOaqiKjswIDAQAB-----END PUBLIC KEY-----';

    public function __construct()
    {
    }    public function publicEncrypt($data, $publicKey)
    {        openssl_public_encrypt($data, $encrypted, $publicKey);
        return $encrypted;
    }    public function publicDecrypt($data, $publicKey)
    {        openssl_public_decrypt($data, $decrypted, $publicKey);
        return $decrypted;
    }    public function privateEncrypt($data, $privateKey)
    {        openssl_private_encrypt($data, $encrypted, $privateKey);
        return $encrypted;
    }    public function privateDecrypt($data, $privateKey)
    {        openssl_private_decrypt($data, $decrypted, $privateKey);
        return $decrypted;
    }
}$rsa = new Rsa();// 使用公鑰加密的內容$str = 'IUMBGcLwJECdxUu3LMbeEhGQdoRjCLqFwfZQBO/Odh3tClbq76Tva7yYqTVxexXLmZ3uY8DrOk/XwcVVRr6g9rBnv/zxBxUShCdN0CwkoguvI+6Oju2aUBlM4FhUp+gmasa5YfqylEp1RpsVAp67GMGlxZvp0ekfhFXkjSqAguPd7dKq5YjftP12xOyuJHAzzg7U+eHxffxnneKqXkK7QrfQD6VrLpbYmayPSjMza/RbjXF+d85UeUZUaF25PZ7Y7kD4Yo7/hY/L6peeOkI5//tpl6U4QY9VsFsjAbIpNMsZuNjE/cZ57Kc5WScPsmy0o9wsp5DUEJmu+YYmr6adoA==';$str = base64_decode($str);$pubstr = $rsa->publicDecrypt($str, $rsa->publicKey);echo "公鑰解密:\n", $pubstr, "\n";$privstr = $rsa->privateDecrypt($str, $rsa->privateKey);echo "私鑰解密:\n", $privstr, "\n";

解碼結果以下:

587057-20170102224214144-1475138770.png

相關文章
相關標籤/搜索