我是PHP的新手,也是我的第一个任务。秘密字使用c#加密(TripleDES /
CBC)。相比之下,我发现IV和secretword字节匹配,但不是密钥。
这是可以正常工作的c#代码......
export default DS.RESTSerializer.extend({
normalizeResponse: function(store, primaryModelClass, payload, id, requestType) {
var pluralTypeKey = Ember.String.pluralize(primaryModelClass.modelName);
payload[pluralTypeKey] = payload['data'];
delete payload['data'];
return this._super(store, primaryModelClass, payload, id, requestType);
}
这是我需要帮助的PHP代码......
string epws = secretWord;
byte[] rawdata = Convert.FromBase64CharArray(char[] aArr);
mCryptoService = new TripleDESCryptoServiceProvider();
string key = ASCIIEncoding.ASCII.GetString(rawdata);
key = key.Substring(0, 24);
mCryptoService.Key = ASCIIEncoding.ASCII.GetBytes(key);
byte[] ivB = new byte[8];
Buffer.BlockCopy(rawdata, 31, ivB, 0, 8);
mCryptoService.IV = ivB;
byte[] epwb = Convert.FromBase64String(epws);
ICryptoTransform cryptoTransform = mCryptoService.CreateDecryptor();
MemoryStream ms = new MemoryStream(epwb, 0, epwb.Length);
CryptoStream cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Read);
StreamReader sr = new StreamReader(cs);
return sr.ReadToEnd();
这些是不同的关键。如果我在php中替换c#键,它可以正常工作。
<?php
// dkey is the rawdata passed in as string from database
$byteArray = unpack('C*', $dkey);
$mkey = implode(array_map('chr', $byteArray));
$mkey = base64_decode($mkey);
$iv = substr($mkey, 31, 8);
$mkey = substr($mkey, 0, 24);
// the encrypted secretword passed in as string from database
$epws = base64_decode($epws);
$ok= trim(mcrypt_decrypt(MCRYPT_3DES, $mkey, $epws, MCRYPT_MODE_CBC, $iv));
?>
不知道还能做什么。
答案 0 :(得分:1)
密钥由字节组成,而不是字符。如果你需要一个显示为字符串的键 - 通常你没有 - 那么你应该将它编码为十六进制。如果以后想要使用它,可以再次将十六进制解码为字节数组。
ASCII只有0到127之间的值,其中底部32个字符以及值127不可打印。所以你的C#代码在这个意义上比你的PHP代码更糟糕,它需要最大的改变。
目前,C#代码只是用问号(3F
十六进制,或十六进制的63 - 替换ASCII范围(0-127)之外的字节 - 检查密钥的打印输出。您只需将值为63的每个值替换为128或更高。
显然,这意味着你的密钥失去了熵,平均它只会强一半(在你的例子中是真的,替换了8个字节)。如果你运气不好,那么所有字节都会被转换成问号(大概在65536一次)或两者之间的任何东西,让你极易受到攻击。