2011-10-13 43 views
4

我创建了一个需要使用签名请求进行授权的API。与API签名公钥和私钥对相混淆

我使用的是php openssl_sign和openssl_verify函数。
我理解公钥和私钥的概念(DSA算法)。但基本上我不知道如何实现它。

我从这个例子从工作http://uk.php.net/manual/en/function.openssl-sign.php

<?php 
$data = "Beeeeer is really good.. hic..."; 

// You can get a simple private/public key pair using: 
// openssl genrsa 512 >private_key.txt 
// openssl rsa -pubout <private_key.txt >public_key.txt 

// IMPORTANT: The key pair below is provided for testing only. 
// For security reasons you must get a new key pair 
// for production use, obviously. 

$private_key = <<<EOD 
-----BEGIN RSA PRIVATE KEY----- 
MIIBOgIBAAJBANDiE2+Xi/WnO+s120NiiJhNyIButVu6zxqlVzz0wy2j4kQVUC4Z 
RZD80IY+4wIiX2YxKBZKGnd2TtPkcJ/ljkUCAwEAAQJAL151ZeMKHEU2c1qdRKS9 
sTxCcc2pVwoAGVzRccNX16tfmCf8FjxuM3WmLdsPxYoHrwb1LFNxiNk1MXrxjH3R 
6QIhAPB7edmcjH4bhMaJBztcbNE1VRCEi/bisAwiPPMq9/2nAiEA3lyc5+f6DEIJ 
h1y6BWkdVULDSM+jpi1XiV/DevxuijMCIQCAEPGqHsF+4v7Jj+3HAgh9PU6otj2n 
Y79nJtCYmvhoHwIgNDePaS4inApN7omp7WdXyhPZhBmulnGDYvEoGJN66d0CIHra 
I2SvDkQ5CmrzkW5qPaE2oO7BSqAhRZxiYpZFb5CI 
-----END RSA PRIVATE KEY----- 
EOD; 
$public_key = <<<EOD 
-----BEGIN PUBLIC KEY----- 
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANDiE2+Xi/WnO+s120NiiJhNyIButVu6 
zxqlVzz0wy2j4kQVUC4ZRZD80IY+4wIiX2YxKBZKGnd2TtPkcJ/ljkUCAwEAAQ== 
-----END PUBLIC KEY----- 
EOD; 

$binary_signature = ""; 

// At least with PHP 5.2.2/OpenSSL 0.9.8b (Fedora 7) 
// there seems to be no need to call openssl_get_privatekey or similar. 
// Just pass the key as defined above 
openssl_sign($data, $binary_signature, $private_key, OPENSSL_ALGO_SHA1); 

// Check signature 
$ok = openssl_verify($data, $binary_signature, $public_key, OPENSSL_ALGO_SHA1); 
echo "check #1: "; 
if ($ok == 1) { 
    echo "signature ok (as it should be)\n"; 
} elseif ($ok == 0) { 
    echo "bad (there's something wrong)\n"; 
} else { 
    echo "ugly, error checking signature\n"; 
} 

$ok = openssl_verify('tampered'.$data, $binary_signature, $public_key,  OPENSSL_ALGO_SHA1); 
echo "check #2: "; 
if ($ok == 1) { 
    echo "ERROR: Data has been tampered, but signature is still valid! Argh!\n"; 
} elseif ($ok == 0) { 
    echo "bad signature (as it should be, since data has beent tampered)\n"; 
} else { 
    echo "ugly, error checking signature\n"; 
} 
?> 

但我strugling到如何已了解这可能被实现为URI请求。

私钥和公钥在http get请求中似乎相当大,客户端又能如何生成可以由服务器验证的签名?

回答

2

基本上这里是加密3两件事:公钥

  1. 生成和对私钥
  2. 加密数据与私钥1和公钥
  3. 使用公钥和私钥解密数据2

步骤1只发生一次,您可以生成公钥(或键[RSA])和私钥的两个客户端(或服务器和客户端)

之前发送数据,需要对数据进行签名使用您的私钥(仅为您所知)和公钥(两者均已知),这将创建一个密文(或称为摘要),您可以将其发送给对方(其他客户端或服务器)。另一方面,他们用公钥解密密文,然后用私钥解密实际数据。

这实际上是使用公共私钥加密解密的基础知识。

这些加密和解密的各种版本都可用,做维基百科将会有所帮助。

+0

维基百科可能有点过于复杂的解释,有时你只需要了解这个概念。谢谢 – user866190

1

它看起来不是一个好主意,将密钥与需要签名的HTTP获取请求一起传输。

更好的是已经存储在服务器端的公钥(例如,在客户端数据库中),并从随请求发送的某个标识符(例如用户名)查找它。

你请求的URL应该是这样的:

rtp://api.example.com/username=User1&method=XML&product=shoes&size=5&sex=male&signature=x1cvGgtRfJs4FgG 

客户端将使用私钥(和任何DSA实现)签署请求URL的重要组成部分。

(私钥不应该对所有的转移)