我的API规范如下:
加密算法
API使用AES-128(也称为Rijndael-128)算法,其中包含192位密钥 用于加密和解密敏感信息的CBC模式 - 用户/登录和用户/注册方法中的密码参数,身份验证令牌等。算法的步骤如下:
加密
填充输入数据,使其大小为加密算法块大小的倍数 - 16个字节。如果输入数据的长度是16的倍数,则需要附加另外16个字节的块。每个填充字节的值是填充字节的数量,作为“unsigned char”。也就是说,填充数据的最后一个字节应该始终在0x01和0x10之间。
为加密算法生成一个16字节长的初始化向量(IV)。
使用带有EK和生成的IV的AES-128加密填充数据。
将IV与加密数据相结合。
使用urlsafe Base64对结果进行编码。 urlsafe Base46字母表使用' - '代替'+'和'_'而不是'/'。
解密
Base64-解码输入数据。
提取前16个字节 - 这些是AES算法的IV。
使用带有EK和IV的AES-128解密数据。
读取解密数据的最后一个字节的值,并从其尾部删除那么多字节。
此API的供应商提供的唯一示例是使用mcrypt在PHP中。我对PHP一无所知,也不是加密专家。我需要能够使用ColdFusion 10来表示上述算法。
我首先尝试获取示例PHP文件并在ColdFusion标记或函数库中查找等效项,然后查找具有相同接口的Java库。我只是不知道如何做到这一点。
这里是否有人可以指出我正确的方向,或者离线与我合作协助?
编辑:
这是给出的示例,用于对我提供的用于API的密钥(伙伴密钥和加密密钥)进行“检查”的基本任务。
Object Client.php,有这个构造函数:
public function __construct($hostApiUrl, $partnerKey, $encryptionKey, $token = null)
{
$this->_pk = $partnerKey;
$this->_ek = $encryptionKey;
$this->_crypt = new Crypt($encryptionKey);
$this->_url = rtrim($hostApiUrl, '/') . self::BASE_URL;
if ($token) {
$this->setUserSession($token);
}
}
这是我试图使用的功能:
public function checkKeys()
{
$secret = $this->_encodeParam($this->_ek);
$result = $this->call('partner/checkkeys', array(
'secret' => $secret
));
if (!$result || !$this->_isCodeOk($result->code)) {
return false;
}
return true;
}
因此,当调用此方法时,客户端对象已经具有伙伴密钥和加密密钥。
所以“秘密”是通过使用_encodeParam()方法“编码”所提供的加密密钥来创建的。看起来像这样:
protected function _encodeParam($secret)
{
$secret = "{$secret}:{$this->_pk}";
return $this->_crypt->encrypt($secret);
}
所以秘密附加了伙伴密钥。然后在crypt对象中使用此方法加密(AES_BLOCK_SIZE设置为16):
public function encrypt($data)
{
$pad = self::AES_BLOCK_SIZE - strlen($data) % self::AES_BLOCK_SIZE;
$data .= str_repeat(chr($pad), $pad);
if (stristr(PHP_OS, 'win') !== false) {
$random_source = MCRYPT_RAND;
} else {
$random_source = MCRYPT_DEV_URANDOM;
}
$iv = mcrypt_create_iv(self::AES_BLOCK_SIZE, $random_source);
mcrypt_generic_init($this->_td, $this->_key, $iv);
$data = $iv . mcrypt_generic($this->_td, $data);
mcrypt_generic_deinit($this->_td);
return self::urlsafe_b64encode($data);
}
返回上面的checkKeys()函数,该函数将请求发送给API,然后API返回响应。那个实际的API调用是一个很容易生成的POST,当然,所有这些加密环节,包括MCRYPT库调用,都是我试图确定CF10或Java中的等价物时遇到的问题。
如果我到目前为止得到一个例子,我想我有机会复制crypt对象中的其他函数(那些甚至是必要的,可能不是,因为有些可能被构建到CF encrypt()和decrypt()函数)。然而,这似乎是一个合理的起点。