文章目录
- appkey和Secret 分别是什么?
- App key
- app secret
- Appkey和Secret 因遵循什么原则?
- 代码示例
- 随机生成有效的appkey
- 校验Appkey
- 调用效果
- 小结
appkey和Secret 分别是什么?
App key
App key简称API接口验证序号,是用于验证API接入合法性的。接入哪个网站的API接口,就需要这个网站允许才能够接入,如果简单比喻的话:可以理解成是登陆网站的用户名。
app secret
App secret:的意思为“私匙”,简称api接口密钥,是跟app key配套使用的,可以简单理解成是密码,它是微信公众平台服务号才有的。
Appkey和Secret 因遵循什么原则?
Appkey 随机生成,Secret固定,其中Appkey的生成最好是采用无规则的方式生成。例如:
123456 MD5加密后就生成了32位或者64位的字符串,再将其拆分为若干段,例如拆分成三段,每段有多少个,然后生成一个2000随机乱码字符串中,将secret 插入到2000个字符串中的固定位置,然后检查乱码字符串长度是否附后,然后substring拆你要的加密字符串,然后解密出来看是否能得到原来的明文。
代码示例
随机生成有效的appkey
这里我采用的是 sha256 加密算法。将secret加密后在生成长度为两千的随机字符串,再根据secret的长度进入混合插入。生成可校验的appkey。这里为了方便读者理解所以设计的相对简单明了,实际开发中混合不会是这样有规律的。
/// <summary>
/// 生成Appkey
/// </summary>
/// <param name="secret"></param>
/// <returns>随机生成的有效key</returns>
static string CreateAppkey(string secret)
{
if(!string.IsNullOrWhiteSpace(secret))
{
string sha256 = ComputeSHA256Hash(secret);
string salt = Salt(2000);
StringBuilder stringBuilder = new StringBuilder();
//混淆算法
for (int i = 0; i < secret.Length; i++)
{
stringBuilder.Append(salt[i]);
stringBuilder.Append(sha256[i]);
}
string str=stringBuilder.ToString().Substring(0, secret.Length);
return str;
}
else
{
return secret;
}
}
/// <summary>
/// sha256加密算法
/// </summary>
/// <param name="input">需要加密的字符串</param>
/// <returns>加密后的字符串</returns>
static string ComputeSHA256Hash(string input)
{
StringBuilder builder = new StringBuilder();
using (var sha256 = SHA256.Create())
{
byte[] textData = Encoding.UTF8.GetBytes(input); // 将字符串编码为字节数组
byte[] bytes= sha256.ComputeHash(textData); // 返回 SHA-256 哈希值的字节数组
for (int i = 0; i < bytes.Length; i++)
{
builder.Append(bytes[i].ToString("x2"));
}
return builder.ToString();
}
}
/// <summary>
/// 生成盐
/// </summary>
/// <param name="length">需要生成的盐的长度</param>
/// <returns>所需长度的盐</returns>
static string Salt(int length)
{
StringBuilder stringBuilder = new StringBuilder();
Random random=new Random();
for (int i = 0; i < length; i++)
{
byte[] bytes= System.Text.Encoding.Default.GetBytes(KEY_CHARS[random.Next(KEY_CHARS.Length)].ToString());
stringBuilder.Append(Encoding.Latin1.GetString(bytes));
}
return stringBuilder.ToString();
}
校验Appkey
校验时需要将secret 和appkey同时传入,传入后我们按照加密时对secret的操作再操作一遍,然后按照之前的混淆方式去除我们用来校验的加密部分也就是代码中的名为[aa]的字符串,再取出appkey中用来校验的部分也就是代码中名为【bb】的字节数组。再将其转换为字符串,与aa做比较。
/// <summary>
/// 验签
/// </summary>
/// <param name="key">用户的appkey</param>
/// <returns>是否验签通过</returns>
static bool Sign(string secret, string key)
{
bool state = false;
if(!string.IsNullOrWhiteSpace(key)&&!string.IsNullOrWhiteSpace(secret))
{
string sha256 = ComputeSHA256Hash(secret);
string aa=sha256.Substring(0, secret.Length/2);
StringBuilder stringBuilder = new StringBuilder();
IEnumerable<char> bb = key?.ToList().Where((value, index) => index % 2 != 0)??new List<char>();
string bstr= String.Concat(bb);
if (aa== bstr)
{
state=true;
}
}
return state;
}
调用效果
static void Main()
{
try
{
for (int i = 0; i < 5; i++)
{
string secret=Guid.NewGuid().ToString("N");
string key = CreateAppkey(secret);
Console.WriteLine("AppKey:{0}---Secret:{1}", key, secret);
bool isok = Sign(secret, key);
Console.WriteLine("验签:{0}", isok);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
小结
在对外开放接口的设计中应该要考虑到接口的安全性和可扩展性。以上这种方式我们只需要保存相关的secret就可以完成校验了,不需要将key保存到数据库中。当我们需要生成一个appkey时直接将secret传入生成方法即可。与固定appkey和secret比起来更为方便,也更为安全。