PHP 使用非对称加密算法

PHP 使用非对称加密算法(RSA)

PHP 支持使用 OpenSSL 扩展来实现 RSA 非对称加密。下面是一个简单的示例代码,演示如何使用 OpenSSL 扩展来实现 RSA 非对称加密:

// 生成公钥和私钥
$keyPair = openssl_pkey_new(array(
    'private_key_bits' => 1024,
    'private_key_type' => OPENSSL_KEYTYPE_RSA,
));

// 获取私钥
openssl_pkey_export($keyPair, $privateKey);

// 获取公钥
$publicKey = openssl_pkey_get_details($keyPair)['key'];

// 要加密的数据
$data = 'Hello, world!';

// 使用公钥加密数据
openssl_public_encrypt($data, $encryptedData, $publicKey);

// 使用私钥解密数据
openssl_private_decrypt($encryptedData, $decryptedData, $privateKey);

// 输出解密后的数据
echo $decryptedData;

在上面的代码中,我们首先使用 openssl_pkey_new 函数生成一个 RSA 密钥对,然后分别获取私钥和公钥。接着,我们定义要加密的数据,使用公钥对数据进行加密,再使用私钥对加密后的数据进行解密,最后输出解密后的数据。

需要注意的是,在实际使用中,需要将私钥妥善保存,以防泄漏。同时,还需要注意密钥长度的选择,过短的密钥容易被攻击。一般来说,建议选择 2048 位或更长的密钥。

加密的类型:

在日常设计及开发中,为确保数据传输和数据存储的安全,可通过特定的算法,将数据明文加密成复杂的密文。目前主流加密手段大致可分为单向加密和双向加密。

单向加密:通过对数据进行摘要计算生成密文,密文不可逆推还原。算法代表:Base64,MD5,SHA;

双向加密:与单向加密相反,可以把密文逆推还原成明文,双向加密又分为对称加密和非对称加密。

对称加密:指数据使用者必须拥有相同的密钥才可以进行加密解密,就像彼此约定的一串暗号。算法代表:DES,3DES,AES,IDEA,RC4,RC5;

非对称加密:相对对称加密而言,无需拥有同一组密钥,非对称加密是一种“信息公开的密钥交换协议”。非对称加密需要公开密钥和私有密钥两组密钥,公开密钥和私有密钥是配对起来的,
也就是说使用公开密钥进行数据加密,只有对应的私有密钥才能解密。这两个密钥是数学相关,用某用户密钥加密后的密文,只能使用该用户的加密密钥才能解密。如果知道了其中一个,并
不能计算出另外一个。因此如果公开了一对密钥中的一个,并不会危害到另外一个密钥性质。这里把公开的密钥为公钥,不公开的密钥为私钥。算法代表:RSA,DSA。

以前一直对客户端传给服务器的信息加密这一块一脸懵,如果app里面的用户登录信息被抓包拿到了,大写着 username:root,password:123456, 那不是很尴尬。

偶然做版权输入的时候遇到了rsa,在支付宝支付的时候也接触过,当时不知道这是啥子,现在才知道。

他能保证,客户端给出的信息,只有拥有私钥的服务器才能看,其他人看的都是乱码,嘿嘿。

非对称加密算法
需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。
公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;
如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。
因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
注意以上的一个点,公钥加密的数据,只有对应的私钥才能解密

在日常使用中是酱紫的:
将私钥private_key.pem用在服务器端,公钥发放给android跟ios等前端
客户端用公钥加密过后,数据只能被拥有唯一私钥的服务器看懂。

具体实现:

1、加密解密的第一步是生成公钥、私钥对,私钥加密的内容能通过公钥解密(反过来亦可以)

下载开源RSA密钥生成工具openssl(通常Linux系统都自带该程序),解压缩至独立的文件夹,进入其中的bin目录,执行以下命令:

a、openssl genrsa -out rsa_private_key.pem 1024
b、openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem
c、openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

第一条命令生成原始 RSA私钥文件 rsa_private_key.pem
第二条命令将原始 RSA私钥转换为 pkcs8格式
第三条生成RSA公钥 rsa_public_key.pem

上面几个就可以看出:通过私钥能生成对应的公钥

也有一些网站提供生成rsa公钥私钥的服务:http://www.bm8.com.cn/webtool/rsa/

2、PHP的加密解密类库:

复制代码

<?php


class Rsa {
 
    /**     
     * 获取私钥     
     * @return bool|resource     
     */    
    private static function getPrivateKey() 
    {        
        $abs_path = dirname(__FILE__) . '/rsa_private_key.pem';
        $content = file_get_contents($abs_path);    
        return openssl_pkey_get_private($content);    
    }    

    /**     
     * 获取公钥     
     * @return bool|resource     
     */    
    private static function getPublicKey()
    {   
        $abs_path = dirname(__FILE__) . '/rsa_public_key.pem';
        $content = file_get_contents($abs_path);    
        return openssl_pkey_get_public($content);     
    }

    /**     
     * 私钥加密     
     * @param string $data     
     * @return null|string     
     */    
    public static function privEncrypt($data = '')    
    {        
        if (!is_string($data)) {            
            return null;       
        }        
        return openssl_private_encrypt($data,$encrypted,self::getPrivateKey()) ? base64_encode($encrypted) : null;    
    }    

    /**     
     * 公钥加密     
     * @param string $data     
     * @return null|string     
     */    
    public static function publicEncrypt($data = '')   
    {        
        if (!is_string($data)) {            
            return null;        
        }        
        return openssl_public_encrypt($data,$encrypted,self::getPublicKey()) ? base64_encode($encrypted) : null;    
    }    

    /**     
     * 私钥解密     
     * @param string $encrypted     
     * @return null     
     */    
    public static function privDecrypt($encrypted = '')    
    {        
        if (!is_string($encrypted)) {            
            return null;        
        }        
        return (openssl_private_decrypt(base64_decode($encrypted), $decrypted, self::getPrivateKey())) ? $decrypted : null;    
    }    

    /**     
     * 公钥解密     
     * @param string $encrypted     
     * @return null     
     */    
    public static function publicDecrypt($encrypted = '')    
    {        
        if (!is_string($encrypted)) {            
            return null;        
        }        
    return (openssl_public_decrypt(base64_decode($encrypted), $decrypted, self::getPublicKey())) ? $decrypted : null;    
    }

}

调用demo:

<?php

require_once "Rsa.php";
$rsa = new Rsa();
$data['name'] = 'Tom';
$data['age']  = '20';
$privEncrypt = $rsa->privEncrypt(json_encode($data));
echo '私钥加密后:'.$privEncrypt.'<br>';

$publicDecrypt = $rsa->publicDecrypt($privEncrypt);
echo '公钥解密后:'.$publicDecrypt.'<br>';

$publicEncrypt = $rsa->publicEncrypt(json_encode($data));
echo '公钥加密后:'.$publicEncrypt.'<br>';

$privDecrypt = $rsa->privDecrypt($publicEncrypt);
echo '私钥解密后:'.$privDecrypt.'<br>';

复制代码

PHP实现aes 对称加密

PHP 提供了 OpenSSL 扩展来进行对称加密,其中包括了 AES 加密算法。下面是一个简单的 PHP 代码示例,用于对字符串进行 AES 加密和解密。

// 定义加密密钥和初始化向量
$key = '0123456789abcdef';
$iv = 'fedcba9876543210';

// 待加密的字符串
$plaintext = 'This is a secret message';

// 加密
$ciphertext = openssl_encrypt($plaintext, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $iv);

// 解密
$decrypted = openssl_decrypt($ciphertext, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $iv);

// 输出结果
echo "Plaintext: $plaintext\n";
echo "Ciphertext: " . base64_encode($ciphertext) . "\n";
echo "Decrypted text: $decrypted\n";

在上述示例中,$key 和 i v 分别是加密密钥和初始化向量。 iv 分别是加密密钥和初始化向量。 iv分别是加密密钥和初始化向量。plaintext 是待加密的字符串。openssl_encrypt() 和 openssl_decrypt() 函数用于执行加密和解密操作,第一个参数是待加密或解密的字符串,第二个参数是加密算法,第三个参数是加密密钥,第四个参数是加密选项,第五个参数是初始化向量。

最后,通过 base64_encode() 函数对加密后的字符串进行编码,以便输出结果。

PHP 提供了 OpenSSL 扩展来进行对称加密,其中包括了 3DES(Triple DES)加密算法。下面是一个简单的 PHP 代码示例,用于对字符串进行 3DES 加密和解密。

// 定义加密密钥和初始化向量
$key = '0123456789abcdef01234567';
$iv = '01234567';

// 待加密的字符串
$plaintext = 'This is a secret message';

// 加密
$ciphertext = openssl_encrypt($plaintext, 'des-ede3-cbc', $key, OPENSSL_RAW_DATA, $iv);

// 解密
$decrypted = openssl_decrypt($ciphertext, 'des-ede3-cbc', $key, OPENSSL_RAW_DATA, $iv);

// 输出结果
echo "Plaintext: $plaintext\n";
echo "Ciphertext: " . base64_encode($ciphertext) . "\n";
echo "Decrypted text: $decrypted\n";

在上述示例中,$key 和 i v 分别是加密密钥和初始化向量。 iv 分别是加密密钥和初始化向量。 iv分别是加密密钥和初始化向量。plaintext 是待加密的字符串。openssl_encrypt() 和 openssl_decrypt() 函数用于执行加密和解密操作,第一个参数是待加密或解密的字符串,第二个参数是加密算法,第三个参数是加密密钥,第四个参数是加密选项,第五个参数是初始化向量。

最后,通过 base64_encode() 函数对加密后的字符串进行编码,以便输出结果。

AES(Advanced Encryption Standard)和3DES(Triple Data Encryption Standard)都是对称加密算法,它们的主要区别在于加密的强度和速度。

AES 加密算法是目前被广泛使用的加密算法之一,由美国联邦政府采用,被视为加密领域的国际标准。AES 加密算法有三种不同的密钥长度,分别为 128 位、192 位和 256 位,加密强度更高,而且加密速度也相对较快。

3DES 加密算法是 DES 加密算法的增强版,采用三次 DES 加密运算,其密钥长度为 168 位,加密强度较高,但加密速度相对较慢。

因此,对于对称加密来说,如果需要更高的加密强度和更快的加密速度,建议使用 AES 加密算法。如果对于加密速度要求不是特别高,但需要更高的加密强度,可以考虑使用 3DES 加密算法。

如果使用相同的加密密钥和初始化向量,多次运行 AES 加密函数加密同一个值,得到的加密结果是相同的。

这是因为 AES 是一种对称加密算法,其加密过程基于密钥和初始化向量,相同的密钥和初始化向量会得到相同的加密结果。因此,如果需要避免相同的明文加密结果相同的问题,可以在每次加密时使用不同的初始化向量,或者使用一次性密钥等其他加密方案。

需要注意的是,为了确保加密结果的唯一性,不能简单地使用固定的初始化向量,因为这会导致加密的结果具有可预测性,容易被攻击者破解。最好的方式是在每次加密时,随机生成一个初始化向量,以确保加密结果的唯一性和安全性。

php实现 DSA 非对称加密

DSA算法是一种非对称加密算法,它常用于数字签名。DSA算法不支持加密和解密操作,只支持签名和验证操作。如果需要进行加密和解密操作,可以使用RSA算法。
PHP提供了openssl扩展来实现DSA算法的非对称加密。以下是使用openssl扩展实现DSA算法非对称加密的基本步骤:

1生成DSA密钥对
使用openssl_pkey_new函数生成一个新的密钥对,可以指定密钥的长度。生成的密钥对是一个资源类型的值,需要用openssl_pkey_get_details函数来获取公钥和私钥

$config = array(
    "digest_alg" => "sha512",
    "private_key_bits" => 2048,
    "private_key_type" => OPENSSL_KEYTYPE_DSA,
);
$res = openssl_pkey_new($config);
$details = openssl_pkey_get_details($res);
$private_key = $details['dsa'];
$public_key = $details['dsa']['pub_key'];

2.对数据进行签名

使用openssl_sign函数对需要签名的数据进行签名,需要传入需要签名的数据、私钥和签名算法(这里使用SHA256算法)。

$data = "hello, world!";
openssl_sign($data, $signature, $private_key, OPENSSL_ALGO_SHA256);

3.验证签名

使用openssl_verify函数对签名进行验证,需要传入原始数据、签名数据、公钥和签名算法。

$data = "hello, world!";
$result = openssl_verify($data, $signature, $public_key, OPENSSL_ALGO_SHA256);
if ($result == 1) {
    echo "Signature is valid.\n";
} elseif ($result == 0) {
    echo "Signature is invalid.\n";
} else {
    echo "Verification error.\n";
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值