我正在尝试编写通过网络从外部 API 请求信息的客户端代码。
除了如何生成授权密钥的规定外,API 很简单(对我来说)。首先是一些上下文:开始需要 6 个字符串值:
- 令牌
- 密码
- 设备 ID
- 盐
- 组织 ID
- 给定密钥
现在是加密的东西。首先是 SHA2。
hashedString = SHA2(token + password + devId)
紧随其后的是 AES。
authKey = AES(salt + orgId + "=" + hashedString)
AES 参数指定如下:
- 模式 = 欧洲央行
- 填充 = PKCS5Padding
- 密钥 = givenKey
我的问题是我对密码学几乎一无所知。
下面是我试图完成上述操作的代码。
// Generate Authorisation key
byte[] fieldsBytes = Encoding.ASCII.GetBytes(token + password + devId);
byte[] keyBytes = Encoding.ASCII.GetBytes(secretKey);
SHA512 shaM = new SHA512Managed();
string hashedFields = Encoding.ASCII.GetString(shaM.ComputeHash(fieldsBytes));
byte[] encryptedBytes = EncryptStringToBytes_Aes(salt + orgId + "=" + hashedfields,
keyBytes, keyBytes);
string encryptedString = Encoding.ASCII.GetString(encryptedBytes);
private byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
{
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
byte[] encrypted;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
aesAlg.Padding = PaddingMode.PKCS7;
aesAlg.Mode = CipherMode.ECB;
// Create an encryptor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor();
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
// Return the encrypted bytes from the memory stream.
return encrypted;
}
此代码从外部服务获得“401”。
我的第一个问题是似乎没有名为SHA2的 NET 方法。我能找到的最接近的是 SHA512,我不确定 SHA512 是否是 SHA2 的 .NET 实现。
其次,AES 的填充已被指定为 PKCS5Padding 但我能找到的最接近(命名方式)的是PKCS7,我不确定它与PKCS5有多么相似。
还有一个初始化向量 (IV)的问题,AES 参数没有指定,但我看到 C# AES 示例包括。在代码中,出于绝望,我已将其设置为与 Key 具有相同的值(我相信这是 API 所称的“秘密密钥”),但我尝试在不将 IV 设置为任何值的情况下发出请求,但仍然得到回一个401。
我可能还应该提到我正在使用ASCII编码来转换字节,因为我第一次尝试使用UTF8,但是当实际发出 HTTP 请求时,我收到一个异常,说头值(记住我们正在生成HTTP 请求标头中的授权密钥)只能以 ASCII 编码。
任何为我指明正确方向的帮助都将不胜感激,因为我对这些密码学的东西感到非常遗憾。