【问题标题】:PHP RSA encryption using private key and PKCS1使用私钥和 PKCS1 的 PHP RSA 加密
【发布时间】:2016-01-11 09:56:00
【问题描述】:

我需要使用 RSA、PKCS1、私钥和 PHP 加密字符串。我什至找不到可以与 exec() 一起使用的终端命令。有人知道怎么做吗?

谢谢!

【问题讨论】:

    标签: php openssl rsa encryption-asymmetric private-key


    【解决方案1】:

    试试phpseclib, a pure PHP RSA implementation:

    <?php
    include('Crypt/RSA.php');
    
    $rsa = new Crypt_RSA();
    //extract($rsa->createKey());
    
    $plaintext = 'terrafrost';
    
    $rsa->loadKey($privatekey);
    $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
    $ciphertext = $rsa->encrypt($plaintext);
    
    echo $plaintext;
    ?>
    

    安全警告:如果您要使用 phpseclib,请确保您follow the best practices for RSA encryption。另请参阅this answer 了解更多详细信息和替代方法。

    【讨论】:

      【解决方案2】:

      如果您启用了 php_openssl 扩展,您可以在不使用命令行的情况下执行此操作,而不是创建密钥。如果您愿意,您甚至可以使用 php 创建密钥。

      生成您的密钥

      这些是生成密钥的 shell 命令。您可以在 Linux、Mac、Cygwin 甚至您的 Windows Git BASH 中运行它们。

      生成 512 位 rsa 私钥。这将要求您输入密码。您需要安全地存储它。

      openssl genrsa -des3 -out private.pem 512

      根据私钥生成公钥。您可以以不安全的方式随意存储它。

      openssl rsa -in private.pem -pubout -out public.pem

      使用 PHP 通过您的密钥加密/解密数据

      请注意,我已经包括使用公钥和私钥进行加密和解密。您只想选择其中一种来实现,例如使用私有加密和公共解密。

      <?php
      $privateKeyPassphrase = "mypassword";
      $sensitiveData = "This is the data that we want to encrypt.";
      
      /*
      // Load the keys from a file (as you would most likely do in a production environment)
      $priv_key_file_name = realpath("private.pem");
      $publ_key_file_name = realpath("public.pem");
      
      // Note: This function needs an array of parameters!
      $privateKey = openssl_pkey_get_private(array("file://$priv_key_file_name", $privateKeyPassphrase));
      $publicKey = openssl_pkey_get_public(array("file://$publ_key_file_name", $privateKeyPassphrase));
      */
      
      // Get keys from a string so that this example can be run without the need for extra files
      $privateKeyString = <<<PK
      -----BEGIN RSA PRIVATE KEY-----
      Proc-Type: 4,ENCRYPTED
      DEK-Info: DES-EDE3-CBC,D21679087FE8490E
      
      hXTtfXC4qYNoE9hySVwPD+Mwhb7RiCae589Z952Z+ucz9i8j+1MO4Sx2nOMCH5Eg
      uotMSr3FipJ/Bqbh66AqqYK3PG7NFYA41f/7xrTA6gwq6MDjmAy6z8TW+NE3OCpF
      n+9zPzT15wcNm4U4ZRpEO+Fi8cYTLu0LlX+k8Djrd+CuS6wX4p8SgpAplDrnAiAH
      z3sJtf2+M67yTNT7v/hIJmkebCwES43pTlNrxluJpD7HBl4BGmFWFI+MJ/gPuFn6
      etQjDpzgep0Wn4FKi34IkDQ9kM4/9tWy0Fhf8ytdg0NZshMt/PWRPrNrs+2qLoJu
      1rHc0rtKVvALQOKU+SbxaYVBlEzelxB0XJ2uQMSIs46vHZiUG3Q2JBmlxRshHQse
      8n9CAYmwm++cPmXq06rVMclCJR0pDlOzGQvIgmo4eiY=
      -----END RSA PRIVATE KEY-----
      PK;
      
      $publicKeyString = <<<PK
      -----BEGIN PUBLIC KEY-----
      MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKcNEHgry/zIFpKdKz2E/ksoDkBn00K7
      v2CxB2kHMWjAxgaFPCYs/8gHclSkcJYARKqvU/0Gsc0mrrPtCs5CytcCAwEAAQ==
      -----END PUBLIC KEY-----
      PK;
      
      // Load private key
      $privateKey = openssl_pkey_get_private(array($privateKeyString, $privateKeyPassphrase));
      
      // Load public key
      $publicKey = openssl_pkey_get_public(array($publicKeyString, $privateKeyPassphrase));
      
      if (!$privateKey) {
          echo "Private key NOT OK\n";
      }
      
      if (!$publicKey) {
          echo "Public key NOT OK\n";
      }
      
      if (!openssl_private_encrypt($sensitiveData, $encryptedWithPrivate, $privateKey)) {
          echo "Error encrypting with private key\n";
      }
      
      if (!openssl_public_encrypt($sensitiveData, $encryptedWithPublic, $publicKey)) {
          echo "Error encrypting with public key\n";
      }
      
      if (!openssl_private_decrypt($encryptedWithPublic, $decryptedWithPrivateFromPublic, $privateKey)) {
          echo "Error decrypting with private key what was encrypted with public key\n";
      }
      
      if (!openssl_public_decrypt($encryptedWithPrivate, $decryptedWithPublicFromPrivate, $publicKey)) {
          echo "Error decrypting with public key what was encrypted with private key\n";
      }
      
      echo "Encrypted with public key: " . base64_encode($encryptedWithPublic) . "\n"; // This is different every time
      echo "Encrypted with private key: " . base64_encode($encryptedWithPrivate) . "\n";
      echo "Decrypted with private key what was encrypted with public key: " . $decryptedWithPrivateFromPublic . "\n";
      echo "Decrypted with public key what was encrypted with private key: " . $decryptedWithPublicFromPrivate . "\n";
      

      【讨论】:

      • 忘了提到在现实生活中您会使用 1024/2048/4096 位密钥。我在这里使用了 512 位,这样代码就不会那么长了。
      【解决方案3】:
      openssl aes-256-cbc -a -salt -in inputfile.txt -out encryptedfile.txt -pass pass:thepassword
      openssl aes-256-cbc -d -a -in encryptedfile.txt -out decryptedfile.txt 
      

      可以执行这些,并且应该能够根据需要更改密码。

      【讨论】:

      • 记录:服务器上的任何用户都可以解析正在运行的程序的命令行,通过命令行提供密码来进行任何操作,但使用虚拟数据进行本地测试是一个坏主意。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-20
      • 2013-05-07
      • 2013-06-08
      相关资源
      最近更新 更多