10.2 非对称加密

非对称加密与对称加密不一样的地方在于,非对称加密算法有两个密钥,分别为公钥和私钥,它的安全性比对称加密更好,公钥用来加密,私钥用来解密,如果用公钥对数据进行加密,只有用对应的私钥才能解密,两个密钥不一致,所以叫非对称加密。

它的使用流程原理如图10-4所示。

图 10-4

RSA加密

RSA公钥加密算法在1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出,RSA正是他们三人的姓氏开头字母拼接。RSA是目前公认最有影响力的加密算法,不过并不是不可破解的,在短密钥的情况下,基于现在越来越强大的云计算,也存在被爆破的可能。早在1999年,就有花了五个月时间在一台有3.2G中央内存的Cray C916计算机上成功分解RSA-155(512位)。

RSA的最大问题在于加解密速度慢,整个运算过程相对要消耗不少时间,不过这一些问题在今后计算资源横向扩展的条件下,也不是很大的问题。

我们来测试一下PHP下的RSA加解密,如果希望简单一点,PHP上可以使用phpseclib,下载地址 http://phpseclib.sourceforge.net/ ,不需要配置即可直接使用,首先下载phpseclib,文件结构如图10-5所示。

图 10-5

然后生成密钥,代码如下:


< php

include
'./Crypt/RSA.php' );

$rsa = new Crypt_RSA
();

extract
$rsa->createKey ());

echo "$privatekey<br />$publickey"

生成密钥后,我们来看看加解密代码:


< php

$PUBLIC_KEY ='-----BEGIN PUBLIC KEY-----

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCm418GwRwXmYOC6eb6G6NzCMRt

nan7Jt76kygfmfa2mGRu1Ff8t3bjyrrRPra8LQgcGxO1KZkDPxODsfX2fblXCNCz

EXxYerZIrcQXR4utTMXkQCN7E7egNDlQOqrP0awFZ5OWrYcbDdmgxa2jAEGtR3Fa

m+GpAAH94H1crvcbSwIDAQAB

-----END PUBLIC KEY-----'


$PRIVATE_KEY = '-----BEGIN RSA PRIVATE KEY-----

MIICXAIBAAKBgQCm418GwRwXmYOC6eb6G6NzCMRtnan7Jt76kygfmfa2mGRu1Ff8

t3bjyrrRPra8LQgcGxO1KZkDPxODsfX2fblXCNCzEXxYerZIrcQXR4utTMXkQCN7

E7egNDlQOqrP0awFZ5OWrYcbDdmgxa2jAEGtR3Fam+GpAAH94H1crvcbSwIDAQAB

AoGBAKYm+RTgbfeQ/z33Yd7gZXrB387Cidlied0/ZVMRFm/0iQlOn8sbXWKtFBH/

Pi9bJhfVXWmgYJa61dLn+tnNkhdYsWCHxN3eMlLJ8XuQjvmrofWb1yZtWVblGhbd

O9fSX2RH8m7DOxrV85/oP0qYTKfla8R21hKmdgo9JDeqMRUBAkEA2ZLqpnqXJ2qp

FE3OHnQydnJQllAG7l1egYheQh0JmeI8CVrWjv40sK5clQK6kONj9JscD0ZPdCqq

EVQb5dSWtQJBAMRc0hzEVpgo544lSIZV1sMiWwxVhDLpvuEUJZtSLh52FIt07Rt7

mVV0IExq7Z2bDX1yhHiqYPen7ck0GC0KKf8CQCTp3zPVkrWWTA9sz+6syi78YB3Q

gAyK/NC/QTa4VHuuPX9c0RA7otbjDkQdzWdtnPTQKCeTR0GvR2FfQshwlA0CQGCZ

zWALkxI+JVQ/sUMtHX9X+nTB6Uxmw9nU4H9d2YRw0MCeoDsB/jgU7gLKI+WCLwvE

97ipERUlDw0JzM7zjh8CQEz541yxg7sttBtEV2RZOd+8bMBaRJWXYqN86vn+dSjq

ds4vY6KgESImQ7Y+o30TcgxgjGZlujZMLgqv9E4VmwY=

-----END RSA PRIVATE KEY-----'


include
'Crypt/RSA.php' );

$rsa = new Crypt_RSA
();

$rsa->loadKey
$PUBLIC_KEY ); // 载入公钥

$plaintext = 'phpsec'


$rsa->setEncryptionMode
CRYPT_RSA_ENCRYPTION_PKCS1 );

$ciphertext = $rsa->encrypt
$plaintext );

$rsa->loadKey
$PRIVATE_KEY ); // 载入私钥

echo $ciphertext.'<br />'.'<br />'.'<br />'


echo $rsa->decrypt
$ciphertext );

可以看到$rsa->encrypt($plaintext);函数用来加密,最终用$rsa->decrypt($ciphertext)来解密并输出明文字符串“phpsec”,效果如图10-6所示。

图 10-6

第一行的乱码就是加密后的“phpsec”,通常保存的时候还会用Base64转码一下才好。