在PHP中使用RSA加密和解密文本

在PHP中使用RSA加密和解密文本,php,rsa,Php,Rsa,PHP5.3有没有提供RSA加密/解密而不需要填充的类 我有私钥和公钥,p,q和模 安全警告:此代码段易受攻击。请参阅以获得更好的安全性 您可以使用: 是。看 它给出了PHP中RSA加密和解密以及javascript中RSA加密的示例代码 如果你想加密文本而不是仅仅以10为基数的数字,你还需要一个基数到基数的转换。这就是将文本转换为非常大的数字。文本实际上只是以63为基数书写。26个小写字母加26个大写字母+10个数字+空格字符。代码也在下面 $GETn参数是保存加密函数密钥的文件名。如果你还

PHP5.3有没有提供RSA加密/解密而不需要填充的类

我有私钥和公钥,p,q和模

安全警告:此代码段易受攻击。请参阅以获得更好的安全性

您可以使用:


是。看

它给出了PHP中RSA加密和解密以及javascript中RSA加密的示例代码

如果你想加密文本而不是仅仅以10为基数的数字,你还需要一个基数到基数的转换。这就是将文本转换为非常大的数字。文本实际上只是以63为基数书写。26个小写字母加26个大写字母+10个数字+空格字符。代码也在下面

$GETn参数是保存加密函数密钥的文件名。如果你还没有弄明白,就去问吧。我会帮忙的

事实上,我昨天发布了整个加密库,但是Brad Larson一个mod,杀了它,并说这种东西并不是堆栈溢出的真正含义。但是您仍然可以在上面的链接中找到所有代码示例和整个函数库,以便为AJAX执行客户机/服务器加密解密

function RSAencrypt( $num, $GETn){
    if ( file_exists( 'temp/bigprimes'.hash( 'sha256', $GETn).'.php')){
        $t= explode( '>,', file_get_contents('temp/bigprimes'.hash( 'sha256', $GETn).'.php'));
        return JL_powmod( $num, $t[4], $t[10]); 
    }else{
        return false;
    }
}

function RSAdecrypt( $num, $GETn){
    if ( file_exists( 'temp/bigprimes'.hash( 'sha256', $GETn).'.php')){
        $t= explode( '>,', file_get_contents('temp/bigprimes'.hash( 'sha256', $GETn).'.php'));
        return JL_powmod( $num, $t[8], $t[10]);     
    }else{
        return false;
    }
}

function JL_powmod( $num, $pow, $mod) {
    if ( function_exists('bcpowmod')) {
        return bcpowmod( $num, $pow, $mod);
    }
    $result= '1';
    do {
        if ( !bccomp( bcmod( $pow, '2'), '1')) {
            $result = bcmod( bcmul( $result, $num), $mod);
        }
       $num = bcmod( bcpow( $num, '2'), $mod);

       $pow = bcdiv( $pow, '2');
    } while ( bccomp( $pow, '0'));
    return $result;
}

function baseToBase ($message, $fromBase, $toBase){
    $from= strlen( $fromBase);
    $b[$from]= $fromBase; 
    $to= strlen( $toBase);
    $b[$to]= $toBase; 

    $result= substr( $b[$to], 0, 1);

    $f= substr( $b[$to], 1, 1);

    $tf= digit( $from, $b[$to]);

    for ($i=strlen($message)-1; $i>=0; $i--){
        $result= badd( $result, bmul( digit( strpos( $b[$from], substr( $message, $i, 1)), $b[$to]), $f, $b[$to]), $b[$to]);
        $f= bmul($f, $tf, $b[$to]);
    }
    return $result;
} 

function digit( $from, $bto){   
    $to= strlen( $bto);
    $b[$to]= $bto; 

    $t[0]= intval( $from);
    $i= 0;
    while ( $t[$i] >= intval( $to)){
        if ( !isset( $t[$i+1])){ 
            $t[$i+1]= 0;
        }
        while ( $t[$i] >= intval( $to)){
            $t[$i]= $t[$i] - intval( $to);
            $t[$i+1]++;
        }
        $i++;
    }

    $res= '';
    for ( $i=count( $t)-1; $i>=0; $i--){ 
        $res.= substr( $b[$to], $t[$i], 1);
    }
    return $res;
}   

function badd( $n1, $n2, $nbase){
    $base= strlen( $nbase);
    $b[$base]= $nbase; 

    while ( strlen( $n1) < strlen( $n2)){
        $n1= substr( $b[$base], 0, 1) . $n1;
    }
    while ( strlen( $n1) > strlen( $n2)){
        $n2= substr( $b[$base], 0, 1) . $n2;
    }
    $n1= substr( $b[$base], 0, 1) . $n1;    
    $n2= substr( $b[$base], 0, 1) . $n2;
    $m1= array();
    for ( $i=0; $i<strlen( $n1); $i++){
        $m1[$i]= strpos( $b[$base], substr( $n1, (strlen( $n1)-$i-1), 1));
    }   
    $res= array();
    $m2= array();
    for ($i=0; $i<strlen( $n1); $i++){
        $m2[$i]= strpos( $b[$base], substr( $n2, (strlen( $n1)-$i-1), 1));
        $res[$i]= 0;
    }           
    for ($i=0; $i<strlen( $n1)  ; $i++){
        $res[$i]= $m1[$i] + $m2[$i] + $res[$i];
        if ($res[$i] >= $base){
            $res[$i]= $res[$i] - $base;
            $res[$i+1]++;
        }
    }
    $o= '';
    for ($i=0; $i<strlen( $n1); $i++){
        $o= substr( $b[$base], $res[$i], 1).$o;
    }   
    $t= false;
    $o= '';
    for ($i=strlen( $n1)-1; $i>=0; $i--){
        if ($res[$i] > 0 || $t){    
            $o.= substr( $b[$base], $res[$i], 1);
            $t= true;
        }
    }
    return $o;
}
function bmul( $n1, $n2, $nbase){
    $base= strlen( $nbase);
    $b[$base]= $nbase; 

    $m1= array();
    for ($i=0; $i<strlen( $n1); $i++){
        $m1[$i]= strpos( $b[$base], substr($n1, (strlen( $n1)-$i-1), 1));
    }   
    $m2= array();
    for ($i=0; $i<strlen( $n2); $i++){
        $m2[$i]= strpos( $b[$base], substr($n2, (strlen( $n2)-$i-1), 1));
    }           
    $res= array();
    for ($i=0; $i<strlen( $n1)+strlen( $n2)+2; $i++){
        $res[$i]= 0;
    }
    for ($i=0; $i<strlen( $n1)  ; $i++){
        for ($j=0; $j<strlen( $n2)  ; $j++){
            $res[$i+$j]= ($m1[$i] * $m2[$j]) + $res[$i+$j];
            while ( $res[$i+$j] >= $base){
                $res[$i+$j]= $res[$i+$j] - $base;
                $res[$i+$j+1]++;
            }
        }
    }
    $t= false;
    $o= '';
    for ($i=count( $res)-1; $i>=0; $i--){
        if ($res[$i]>0 || $t){  
            $o.= substr( $b[$base], $res[$i], 1);
            $t= true;
        }
    }
    return $o;
}
函数RSAencrypt($num,$GETn){
如果(文件_存在('temp/bigprimes'.hash('sha256',$GETn.'.php')){
$t=explode('>,',file_get_contents('temp/bigprimes'.hash('sha256',$GETn)。'.php');
返回JL_powmod($num,$t[4],$t[10]);
}否则{
返回false;
}
}
函数RSAdecrypt($num,$GETn){
如果(文件_存在('temp/bigprimes'.hash('sha256',$GETn.'.php')){
$t=explode('>,',file_get_contents('temp/bigprimes'.hash('sha256',$GETn)。'.php');
返回JL_powmod($num,$t[8],$t[10]);
}否则{
返回false;
}
}
函数JL_powmod($num,$pow,$mod){
如果(函数_存在('bcpowmod')){
返回bcpowmod($num,$pow,$mod);
}
$result='1';
做{
如果(!bccomp(bcmod($pow,'2'),'1')){
$result=bcmod(bcmul($result,$num),$mod);
}
$num=bcmod(bcpow($num,'2'),$mod);
$pow=bcdiv($pow,'2');
}而(bccomp($pow,'0'));
返回$result;
}
基于函数的数据库($message、$fromBase、$toBase){
$from=strlen($fromBase);
$b[$from]=$fromBase;
$to=strlen($toBase);
$b[$to]=$toBase;
$result=substr($b[$to],0,1);
$f=substr($b[$to],1,1);
$tf=数字($from,$b[$to]);
对于($i=strlen($message)-1;$i>=0;$i--){
$result=badd($result,bmul(数字(strpos($b[$from],substr($message,$i,1)),$b[$to]),$f,$b[$to]),$b[$to]);
$f=bmul($f,$tf,$b[$to]);
}
返回$result;
} 
函数位($from,$bto){
$to=strlen($bto);
$b[$to]=$bto;
$t[0]=intval($from);
$i=0;
而($t[$i]>=intval($to)){
如果(!isset($t[$i+1]){
$t[$i+1]=0;
}
而($t[$i]>=intval($to)){
$t[$i]=$t[$i]-intval($to);
$t[$i+1]++;
}
$i++;
}
$res='';
对于($i=count($t)-1;$i>=0;$i--){
$res.=substr($b[$to],$t[$i],1);
}
返回$res;
}   
功能添加($n1、$n2、$nbase){
$base=strlen($nbase);
$b[$base]=$nbase;
而(斯特伦($n1)<斯特伦($n2)){
$n1=substr($b[$base],0,1)。$n1;
}
而(斯特伦($n1)>斯特伦($n2)){
$n2=substr($b[$base],0,1)。$n2;
}
$n1=substr($b[$base],0,1)。$n1;
$n2=substr($b[$base],0,1)。$n2;
$m1=数组();

对于($i=0;$i2017年(或以后)编写的任何打算采用严格加密技术的应用程序,都不应再使用RSA

当人们决定使用RSA加密时,会犯两大错误:

  • 开发者选择
  • 由于RSA本身无法加密很长的字符串,所以开发人员通常会将字符串分成小块,并独立加密每个块
  • 最佳选择:
    钠加密盒密封()
    简单且安全。libnaid将在PHP7.2中提供,或通过PECL提供早期版本的PHP。如果您需要纯PHP polyfill,请获取

    勉强:正确使用RSA 2017年使用RSA的唯一原因是,“我被禁止安装PECL扩展,因此不能,并且由于某些原因也不能使用paragonie/Na钠_-compat。”

    您的协议应该如下所示:

  • 生成一个随机AES密钥
  • 使用AEAD加密模式或CBC-then HMAC-SHA256加密模式,使用AES密钥加密明文消息
  • 使用RSA公钥加密AES密钥(步骤1)
  • 连接RSA加密的AES密钥(步骤3)和AES加密的消息(步骤2)
  • 与其自己实现,不如检查一下


    进一步阅读:

    < P>如果你使用PHP>=7.2,考虑使用内置钠核心扩展进行包封。

    它是现代的,更安全。你可以在这里找到更多信息-。在这里-

    PHP7.2钠加密类示例-

    <?php
    
    /**
     * Simple sodium crypto class for PHP >= 7.2
     * @author MRK
     */
    class crypto {
    
        /**
         * 
         * @return type
         */
        static public function create_encryption_key() {
            return base64_encode(sodium_crypto_secretbox_keygen());
        }
    
        /**
         * Encrypt a message
         * 
         * @param string $message - message to encrypt
         * @param string $key - encryption key created using create_encryption_key()
         * @return string
         */
        static function encrypt($message, $key) {
            $key_decoded = base64_decode($key);
            $nonce = random_bytes(
                    SODIUM_CRYPTO_SECRETBOX_NONCEBYTES
            );
    
            $cipher = base64_encode(
                    $nonce .
                    sodium_crypto_secretbox(
                            $message, $nonce, $key_decoded
                    )
            );
            sodium_memzero($message);
            sodium_memzero($key_decoded);
            return $cipher;
        }
    
        /**
         * Decrypt a message
         * @param string $encrypted - message encrypted with safeEncrypt()
         * @param string $key - key used for encryption
         * @return string
         */
        static function decrypt($encrypted, $key) {
            $decoded = base64_decode($encrypted);
            $key_decoded = base64_decode($key);
            if ($decoded === false) {
                throw new Exception('Decryption error : the encoding failed');
            }
            if (mb_strlen($decoded, '8bit') < (SODIUM_CRYPTO_SECRETBOX_NONCEBYTES + SODIUM_CRYPTO_SECRETBOX_MACBYTES)) {
                throw new Exception('Decryption error : the message was truncated');
            }
            $nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
            $ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
    
            $plain = sodium_crypto_secretbox_open(
                    $ciphertext, $nonce, $key_decoded
            );
            if ($plain === false) {
                throw new Exception('Decryption error : the message was tampered with in transit');
            }
            sodium_memzero($ciphertext);
            sodium_memzero($key_decoded);
            return $plain;
        }
    
    }
    

    我很难解密用python加密的长字符串。以下是python加密函数:

    def RSA_encrypt(public_key, msg, chunk_size=214):
        """
        Encrypt the message by the provided RSA public key.
    
        :param public_key: RSA public key in PEM format.
        :type public_key: binary
        :param msg: message that to be encrypted
        :type msg: string
        :param chunk_size: the chunk size used for PKCS1_OAEP decryption, it is determined by \
        the private key length used in bytes - 42 bytes.
        :type chunk_size: int
        :return: Base 64 encryption of the encrypted message
        :rtype: binray
        """
        rsa_key = RSA.importKey(public_key)
        rsa_key = PKCS1_OAEP.new(rsa_key)
    
        encrypted = b''
        offset = 0
        end_loop = False
    
        while not end_loop:
            chunk = msg[offset:offset + chunk_size]
    
            if len(chunk) % chunk_size != 0:
                chunk += " " * (chunk_size - len(chunk))
                end_loop = True
    
            encrypted += rsa_key.encrypt(chunk.encode())
            offset += chunk_size
    
        return base64.b64encode(encrypted)
    
    PHP中的解密:

    /**
     * @param  base64_encoded string holds the encrypted message.
     * @param  Resource your private key loaded using openssl_pkey_get_private
     * @param  integer Chunking by bytes to feed to the decryptor algorithm.
     * @return String decrypted message.
     */
    public function RSADecyrpt($encrypted_msg, $ppk, $chunk_size=256){
        if(is_null($ppk))
            throw new Exception("Returned message is encrypted while you did not provide private key!");
        $encrypted_msg = base64_decode($encrypted_msg);
    
        $offset = 0;
        $chunk_size = 256;
    
        $decrypted = "";
        while($offset < strlen($encrypted_msg)){
            $decrypted_chunk = "";
            $chunk = substr($encrypted_msg, $offset, $chunk_size);
    
            if(openssl_private_decrypt($chunk, $decrypted_chunk, $ppk, OPENSSL_PKCS1_OAEP_PADDING))
                $decrypted .= $decrypted_chunk;
            else 
                throw new exception("Problem decrypting the message");
            $offset += $chunk_size;
        }
        return $decrypted;
    }
    
    /**
    *@param base64_编码字符串保存加密消息。
    *@param Resource使用openssl_pkey_get_private加载您的私钥
    *@param整数按字节分块以馈送到解密算法。
    *@return字符串已解密消息。
    */
    公共函数RSADecyrpt($encrypted_msg,$ppk,$chunk_size=256){
    如果(为空($ppk))
    抛出新异常(“当您未提供私钥时,返回的消息已加密!”);
    $encrypted_msg=base64_decode($encrypted_msg);
    $offset=0;
    $chunk_size=256;
    $decrypted=“”;
    而($offset<?php
    
    /**
     * Simple sodium crypto class for PHP >= 7.2
     * @author MRK
     */
    class crypto {
    
        /**
         * 
         * @return type
         */
        static public function create_encryption_key() {
            return base64_encode(sodium_crypto_secretbox_keygen());
        }
    
        /**
         * Encrypt a message
         * 
         * @param string $message - message to encrypt
         * @param string $key - encryption key created using create_encryption_key()
         * @return string
         */
        static function encrypt($message, $key) {
            $key_decoded = base64_decode($key);
            $nonce = random_bytes(
                    SODIUM_CRYPTO_SECRETBOX_NONCEBYTES
            );
    
            $cipher = base64_encode(
                    $nonce .
                    sodium_crypto_secretbox(
                            $message, $nonce, $key_decoded
                    )
            );
            sodium_memzero($message);
            sodium_memzero($key_decoded);
            return $cipher;
        }
    
        /**
         * Decrypt a message
         * @param string $encrypted - message encrypted with safeEncrypt()
         * @param string $key - key used for encryption
         * @return string
         */
        static function decrypt($encrypted, $key) {
            $decoded = base64_decode($encrypted);
            $key_decoded = base64_decode($key);
            if ($decoded === false) {
                throw new Exception('Decryption error : the encoding failed');
            }
            if (mb_strlen($decoded, '8bit') < (SODIUM_CRYPTO_SECRETBOX_NONCEBYTES + SODIUM_CRYPTO_SECRETBOX_MACBYTES)) {
                throw new Exception('Decryption error : the message was truncated');
            }
            $nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
            $ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
    
            $plain = sodium_crypto_secretbox_open(
                    $ciphertext, $nonce, $key_decoded
            );
            if ($plain === false) {
                throw new Exception('Decryption error : the message was tampered with in transit');
            }
            sodium_memzero($ciphertext);
            sodium_memzero($key_decoded);
            return $plain;
        }
    
    }
    
    <?php 
    
    $key = crypto::create_encryption_key();
    
    $string = 'Sri Lanka is a beautiful country !';
    
    echo $enc = crypto::encrypt($string, $key); 
    echo crypto::decrypt($enc, $key);
    
    def RSA_encrypt(public_key, msg, chunk_size=214):
        """
        Encrypt the message by the provided RSA public key.
    
        :param public_key: RSA public key in PEM format.
        :type public_key: binary
        :param msg: message that to be encrypted
        :type msg: string
        :param chunk_size: the chunk size used for PKCS1_OAEP decryption, it is determined by \
        the private key length used in bytes - 42 bytes.
        :type chunk_size: int
        :return: Base 64 encryption of the encrypted message
        :rtype: binray
        """
        rsa_key = RSA.importKey(public_key)
        rsa_key = PKCS1_OAEP.new(rsa_key)
    
        encrypted = b''
        offset = 0
        end_loop = False
    
        while not end_loop:
            chunk = msg[offset:offset + chunk_size]
    
            if len(chunk) % chunk_size != 0:
                chunk += " " * (chunk_size - len(chunk))
                end_loop = True
    
            encrypted += rsa_key.encrypt(chunk.encode())
            offset += chunk_size
    
        return base64.b64encode(encrypted)
    
    /**
     * @param  base64_encoded string holds the encrypted message.
     * @param  Resource your private key loaded using openssl_pkey_get_private
     * @param  integer Chunking by bytes to feed to the decryptor algorithm.
     * @return String decrypted message.
     */
    public function RSADecyrpt($encrypted_msg, $ppk, $chunk_size=256){
        if(is_null($ppk))
            throw new Exception("Returned message is encrypted while you did not provide private key!");
        $encrypted_msg = base64_decode($encrypted_msg);
    
        $offset = 0;
        $chunk_size = 256;
    
        $decrypted = "";
        while($offset < strlen($encrypted_msg)){
            $decrypted_chunk = "";
            $chunk = substr($encrypted_msg, $offset, $chunk_size);
    
            if(openssl_private_decrypt($chunk, $decrypted_chunk, $ppk, OPENSSL_PKCS1_OAEP_PADDING))
                $decrypted .= $decrypted_chunk;
            else 
                throw new exception("Problem decrypting the message");
            $offset += $chunk_size;
        }
        return $decrypted;
    }