2017-05-09 76 views
-1

我想電子郵件地址存儲在數據庫中,但因爲它是一個共享的一個,我想他們存儲加密後並在需要時解密。
我以爲加密了它的第一部分(@)之前的,所以我想出了這樣的事情:
真實的電子郵件:[email protected] 加密的期望:[email protected]加密 - 解密OpenSSL的PHP​​中只包含字母

的proble就是當我使用這樣的功能:

function EncryptVar($sVar){ 

return openssl_encrypt($sVar, $this->encryptionMethod, $this->secretHash); 

} 

一些祕密的散列,這下面的方法

$this->secretHash = "25c6c7ff35b9979b151f2136cd1sdftrez"; 
$this->encryptionMethod = "AES-256-CBC"; 

我可能會在加密部分使用特殊字符,因此是無效的電子郵件地址格式。
有沒有辦法使用這種方法,所以我只有字母和數字?

+1

爲什麼你關心電子郵件地址格式是否有效後,你加密它的第一部分? (它只需要在加密之前和解密後有效,糾正我,如果我錯了) – Rabin

+0

嗨@Rabin,因爲它是一些Web服務中使用的共享數據庫,它是強制性的在他們的分貝,電子郵件格式是尊重和出於道德和法律方面的原因,我不想給客戶真實的電子郵件地址。在一些加密,我有這樣的:「4n095tOA8PpRq5Nw2tIEp8l47m/[email protected]」,這是不是一個有效的電子郵件格式 – Lebach

+0

等什麼呢?數據庫強制在此字段上進行電子郵件驗證?或者你是否通過API進行數據驗證。如果是後者,你可以使用'bin2hex'(代替base64編碼)給你這樣的東西。 'E27D3DE6D380F0FA51AB9370DAD204A7C978EE6FD5471C794912F4663174D517 @ gmail.com' – Rabin

回答

0

解決這一問題的常用方法是使用編碼base64_encode/base64_decode /解碼。這會將您的二進制數據轉換爲ASCII字符串。

+0

嗨@ this.lau_,問題是我不能讓任何人輕鬆解碼他們的法律和道德問題,因此我需要使用私鑰或祕密散列... – Lebach

+0

@Lebach,是的我的意思是你首先加密它與你的函數EncryptVar,然後你用'base64_encode'編碼。如果需要,可以去掉最後的「=」字符,因爲該字符串仍然可以使用base64_decode正確解碼。但請注意「=」,「/」等是[有效的電子郵件字符](http://stackoverflow.com/a/2049510/561309),因此您無需剝離它們。 –

0

有,所以我只有字母和數字使用此方法的方法嗎?

這是一個很好的使用base32-encoding的地方。

一個很好的實現這是this library可用。

使用安全的加密方法的一個例子:

<?php 
use ParagonIE\ConstantTime\Base32; 

class EmailEncryption 
{ 
    protected $key; 

    public function __construct($key) 
    { 
     if (mb_strlen($key, '8bit') !== 32) { 
      throw new Exception('Keys should be 32 bytes generated from /dev/urandom'); 
     } 
    } 

    /** 
    * @param string $sVar 
    * @return string 
    */ 
    public function encryptVar($sVar) 
    { 
     $nonce = random_bytes(12); 
     $tag = ''; 
     $encrypted = openssl_encrypt(
      $sVar, 
      'aes-256-gcm', 
      $this->key, 
      OPENSSL_RAW_DATA, 
      $nonce, 
      $tag 
     ); 
     return Base32::encode($tag . $nonce . $encrypted); 
    } 

    /** 
    * @param string $sVar 
    * @return string 
    */ 
    public function decryptVar($sVar) 
    { 
     $decoded = Base32::decode($sVar); 
     $tag = mb_substr($decoded, 0, 16, '8bit'); 
     $nonce = mb_substr($decoded, 16, 12, '8bit'); 
     $ciphertext = mb_substr($decoded, 28, null, '8bit'); 
     $plaintext = openssl_decrypt(
      $ciphertext, 
      'aes-256-gcm', 
      $this->key, 
      OPENSSL_RAW_DATA, 
      $nonce, 
      $tag 
     ); 
     if (is_bool($plaintext)) { 
      throw new Exception('Invalid ciphertext'); 
     } 
     return $plaintext; 
    } 
} 

用法:

$key = random_bytes(32); 
$encrypter = new EmailEncryption($key); 

$message = 'test123456789'; 
$ciphertext = $encrypter->encryptVar($message); 
var_dump($ciphertext); 
$plaintext = $encrypter->decryptVar($ciphertext); 
var_dump($plaintext, $message); 

注:這需要PHP 7.1+,但給你認證加密。