最安全的方法是使用 SSL 通道并要求身份验证。如果身份验证通过,那么您可以将某种会话密钥(可以是随机生成的字符串)返回给客户端,并在每次请求时检查它。
如果您的服务不允许使用 SSL,那么您可以尝试为您的合作伙伴添加简单的用户名/密码身份验证,但在这种情况下,如果有人拦截您的通信,他们可以使用相同的凭据访问您的服务。
另一种方法是在每个请求上使用签名。例如,您可以为此目的使用 GPG。您的服务器持有所有合作伙伴的公钥。当合作伙伴想要向您的服务器进行查询时,他只需使用他的私钥签署他的请求,并且在收到您将能够安全地验证此请求是由特定合作伙伴发送的并且它 100% 不是伪造的。
编辑
对于 GPG,您需要安装名为gnupg的 PECL 模块。这是我们框架中利用 GPG 功能的类。
class GPG
{
/**
* Encrypt given data to one or more recipients
*
* @param string $string
* @param string|array $encryptKeyID
* @param bollean $armour
* @return string
*/
public static function encrypt($string, $encryptKeyID, $armour = true){
$gpg = new Crypt_GPG();
if(is_array($encryptKeyID)){
foreach($encryptKeyID as $keyId){
$gpg->addEncryptKey($keyId);
}
}
else{
$gpg->addEncryptKey($encryptKeyID);
}
return $gpg->encrypt($string, $armour);
}
/**
* Decrypt given data
*
* @param string $string
* @param string $keyPassword
* @param string $keyID
* @return string
*/
public static function decrypt($string, $keyID, $keyPassword = null){
$gpg = new Crypt_GPG();
$gpg->addDecryptKey($keyID, $keyPassword);
return $gpg->decrypt($string);
}
/**
* Sign given string
*
* @param string $string
* @param string $keyID
* @param string $keyPassword
* @param boolean $mode
* @param boolean $armor
* @return string
*/
public static function sign($string, $keyID, $keyPassword = null, $mode = null, $armor = true){
$gpg = new Crypt_GPG();
if($mode === null){
$mode = Crypt_GPG::SIGN_MODE_CLEAR;
}
$gpg->addSignKey($keyID, $keyPassword);
return $gpg->sign($string, $mode);
}
/**
* Verify signature of given message
*
* @param string $string
* @return boolean
*/
public static function verify($string){
$gpg = new Crypt_GPG();
$signatures = $gpg->verify($string);
if ($signatures[0]->isValid()) {
return true;
}
else{
return false;
}
}
/**
* Encrypt and sign given string to one or more recipients
*
* @param string $string
* @param string|array $encryptKeyID
* @param string $signkeyID
* @param string $signkeyPassword
* @param boolean $mode
* @param boolean $armor
* @return string
*/
public static function encryptAndSign($string, $encryptKeyID, $signkeyID, $signkeyPassword = null, $mode = null, $armor = true){
$gpg = new Crypt_GPG();
if($mode === null){
$mode = Crypt_GPG::SIGN_MODE_CLEAR;
}
$gpg->addSignKey($signkeyID, $signkeyPassword);
if(is_array($encryptKeyID)){
foreach($encryptKeyID as $keyId){
$gpg->addEncryptKey($keyId);
}
}
else{
$gpg->addEncryptKey($encryptKeyID);
}
return $gpg->encryptAndSign($string, $armor);
}
/**
* Decrypt and verify given string
*
* @param string $string
* @param string $keyID
* @param string $keyPassword
* @return array|false
*/
public static function decryptAndVerify($string, $keyID, $keyPassword = null){
$gpg = new Crypt_GPG();
$gpg->addDecryptKey($keyID, $keyPassword);
$result = $gpg->decryptAndVerify($string);
if(empty($result['data']) and empty($result['signatures'])){
return false;
}
if(isset($result['signatures'][0])){
$result['signature'] = $result['signatures'][0]->isValid();
unset($result['signatures']);
}
return $result;
}
}