概括就是:“學會用PHP的openssl擴展??!”
創(chuàng)新互聯(lián)主要從事網(wǎng)頁設(shè)計、PC網(wǎng)站建設(shè)(電腦版網(wǎng)站建設(shè))、wap網(wǎng)站建設(shè)(手機版網(wǎng)站建設(shè))、響應(yīng)式網(wǎng)站設(shè)計、程序開發(fā)、網(wǎng)站優(yōu)化、微網(wǎng)站、小程序制作等,憑借多年來在互聯(lián)網(wǎng)的打拼,我們在互聯(lián)網(wǎng)網(wǎng)站建設(shè)行業(yè)積累了豐富的成都做網(wǎng)站、網(wǎng)站設(shè)計、網(wǎng)站設(shè)計、網(wǎng)絡(luò)營銷經(jīng)驗,集策劃、開發(fā)、設(shè)計、營銷、管理等多方位專業(yè)化運作于一體。
1、先用openssl_pkey_new()函數(shù)產(chǎn)生一個私鑰pri_key,
2、用openssl_csr_new()函數(shù)以私鑰pri_key 產(chǎn)生一個信用證csr
3、用openssl_sign()函數(shù)以私鑰pri_key對一段數(shù)據(jù)data產(chǎn)生一個數(shù)字簽名signature。
4、用openssl_pkey_get_public()函數(shù)從信用證csr中獲得公鑰pub_key
5、把公鑰pub_key、數(shù)字簽名signature、數(shù)據(jù)data發(fā)給對方。
6、對方收到3項后,用openssl_verify()函數(shù)或其他驗證工具,驗證簽名。
7、對方驗證有效,開始使用你的信息data。驗證無效,再找你扯皮。
整個過程的雙方可以互換,即可讓對方出具三項,你來驗證。
附上出處鏈接:
四,用PHP生成密鑰
PEAR::Crypt_RSA的Crypt_RSA_KeyPair類可以生成密鑰。調(diào)用步驟如下:
require_once('Crypt/RSA.php');
$math_obj = Crypt_RSA_MathLoader::loadWrapper();
$key_pair = new Crypt_RSA_KeyPair($key_lenth);
if (!$key_pair-isError()){
$public_key = $key_pair-getPublicKey();
$private_key = $key_pair-getPrivateKey();
$e =$math_obj-hexstr($math_obj-bin2int($public_key-getExponent()));
$d =$math_obj-hexstr($math_obj-bin2int($private_key-getExponent()));
$n =$math_obj-hexstr($math_obj-bin2int($public_key-getModulus()));
}
hexstr()是自己添加的函數(shù),用來把十進制字符串轉(zhuǎn)換為十六進制。對Crypt_RSA_Math_GMP很簡單,只需:
function hexstr($num){
return gmp_strval($num,16);
}
對Crypt_RSA_Math_BCMath略麻煩些:
function hexstr($num){
$result = '';
do{
$result = sprintf('%02x',intval(bcmod($num,256))).$result;
$num = bcdiv($num, 256);
}while(bccomp($num, 0));
return ltrim($result,'0');
}
五,用php生成密鑰(二)
為了提高加密速度,一般選一個較小的e。比較常用的是3、17、257、65537幾個素數(shù)。
generate()生成密鑰的算法是依次計算p,q,n,e,d。因此做了如下改動,以便可以自己選e值:
原來的:
function Crypt_RSA_KeyPair($key_len, $wrapper_name = 'default', $error_handler = '')
改后增加一個參數(shù)e:
function Crypt_RSA_KeyPair($key_len, $e = null, $wrapper_name = 'default', $error_handler = '')
這個函數(shù)調(diào)用generate()。效應(yīng)地:
function generate($key_len = null)
也增加一個參數(shù)e:
function generate($key_len = null, $e = null)
把CRYPT_RSA-1.0.0的KeyPair.php中屬于generate()的245~271行改動順序,由e確定p和q:
if($e != null$this-_math_obj-cmpAbs($e,2)0)
$e = $this-_math_obj-nextPrime($this-_math_obj-dec($e));//取個素數(shù)
else
{
while(true)
{
$e = $this-_math_obj-getRand($q_len, $this-_random_generator);
if ($this-_math_obj-cmpAbs($e,2)=0)
continue;
$e = $this-_math_obj-nextPrime($this-_math_obj-dec($e));
break;
}
}
do{
$p = $this-_math_obj-getRand($p_len, $this-_random_generator, true);
$p = $this-_math_obj-nextPrime($p);
do{
do{
$q = $this-_math_obj-getRand($q_len, $this-_random_generator, true);
$tmp_len = $this-_math_obj-bitLen($this-_math_obj-mul($p, $q));
if ($tmp_len $key_len)
$q_len++;
elseif ($tmp_len $key_len)
$q_len--;
} while ($tmp_len != $key_len);
$q = $this-_math_obj-nextPrime($q);
$tmp = $this-_math_obj-mul($p, $q);
} while ($this-_math_obj-bitLen($tmp) != $key_len);
// $n - is shared modulus
$n = $this-_math_obj-mul($p, $q);
// generate public ($e) and private ($d) keys
$pq = $this-_math_obj-mul($this-_math_obj-dec($p), $this-_math_obj-dec($q));
if($this-_math_obj-isZero($this-_math_obj-dec($this-_math_obj-gcd($e, $pq))))
break;
}while(true);
(網(wǎng)易的服務(wù)真體貼啊,連pre標記里面的東西都給改。還改不好)這樣,如果要生成e為3的1024位密鑰,可以如下調(diào)用:
$key_pair = new Crypt_RSA_KeyPair(1024,3);
六,干什么用
加密比較重要的數(shù)據(jù)。比如注冊時用戶輸入的密碼。
登錄時把密碼hmac一下就可以防止重放攻擊(replay attack)了。對注冊不存在這種攻擊,但有密碼泄露的危險。上傳密碼hash那點安全性根本不算什么。這個可以用RSA加密解決。
不過,對中間人攻擊還是沒辦法。
另外一個
以下命令來生成密鑰對。
$openssl genrsa -out mykey.pem 2048
$openssl pkcs8 -topk8 -inform PEM -outform PEM -in mykey.pem \
-out private_key.pem -nocrypt
這個命令得到的公共密鑰。
$ openssl rsa -in mykey.pem -pubout -outform DER -out public_key.der
我寫了兩方法讀取私鑰和公鑰
分別。public PrivateKey getPemPrivateKey(String filename, String algorithm) throws Exception {
File f = new File(filename);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int) f.length()];
dis.readFully(keyBytes);
dis.close();
String temp = new String(keyBytes);
String privKeyPEM = temp.replace("-----BEGIN PRIVATE KEY-----\n", "");
privKeyPEM = privKeyPEM.replace("-----END PRIVATE KEY-----", "");
//System.out.println("Private key\n"+privKeyPEM);
Base64 b64 = new Base64();
byte [] decoded = b64.decode(privKeyPEM);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decoded);
KeyFactory kf = KeyFactory.getInstance(algorithm);
return kf.generatePrivate(spec);
}
public PublicKey getPemPublicKey(String filename, String algorithm) throws Exception {
File f = new File(filename);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int) f.length()];
dis.readFully(keyBytes);
dis.close();
String temp = new String(keyBytes);
String publicKeyPEM = temp.replace("-----BEGIN PUBLIC KEY-----\n", "");
publicKeyPEM = privKeyPEM.replace("-----END PUBLIC KEY-----", "");
Base64 b64 = new Base64();
byte [] decoded = b64.decode(publicKeyPEM);
X509EncodedKeySpec spec =
new X509EncodedKeySpec(decoded);
KeyFactory kf = KeyFactory.getInstance(algorithm);
return kf.generatePublic(spec);
}
1、加米解米的第一步是生成公鑰、私鑰對,私鑰加米的內(nèi)容能通過公鑰解米(反過來亦可以)下載開源RSA米鑰生成工具openssl(通常Linux系統(tǒng)都自帶該程序),解壓縮至獨立的文件夾,進入其中的bin目錄,執(zhí)行以下命令: 復制代碼 代碼如下: openssl ...