110,534
社区成员
发帖
与我相关
我的任务
分享
{
"hash" : "52c17e7b60a06c5b",
"key" : "-----BEGIN PUBLIC KEY-----\nMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANe7Rmtt4U3mjPwixdxLrw9Yczkht8VE\nxECb05iKTGrlXcc3vXuDla1Vjs7EY2xD4se+pAaICeSqS+Rq7yVZKkcCAwEAAQ==\n-----END PUBLIC KEY-----\n"
}
其中的hash值会和密码字符串连接,然后加密。var s = new JSEncrypt;
s.setPublicKey(i.key), // i为上述json
a = s.encrypt(i.hash + a), // a为密码
最后得到的a为加密的密码。
ERROR_MAP = {
"-105": "验证码错误",
"-618": "昵称重复或含有非法字符",
"-619": "昵称不能小于3个字符或者大于30个字符",
"-620": "该昵称已被使用",
"-622": "Email已存在",
"-625": "密码错误次数过多",
"-626": "用户不存在",
"-627": "密码错误",
"-628": "密码不能小于6个字符或大于16个字符",
"-645": "昵称或密码过短",
"-646": "请输入正确的手机号",
"-647": "该手机已绑定另外一个账号",
"-648": "验证码发送失败",
"-652": "历史遗留问题,昵称与手机号重复,请联系管理员",
"-662": "加密后的密码已过期"
}
function init_login() {
$("#login-submit").click(function() {
var e = $(this),
t = $("#login-username").val(),
a = $("#login-passwd").val(),
n = $("#login-captcha").val(),
r = $("#keep-login").attr("checked") ? 1 : 0;
if (!e.hasClass("disabled") && !e.hasClass("loading")) {
if ($("#login .input").removeClass("ok error"), $("#login .message").text(""), "" == t) return $("#login .uname-row .input").error(), void $("#login .message[for=username]").text("手机号/邮箱不能为空");
if ("" == a) return $("#login .passwd-row .input").error(), void $("#login .message[for=passwd]").text("请输入密码");
e.addClass("loading"), $.getJSON("/login?act=getkey&_=" + (new Date).getTime(), function(i) {
if (i && i.error) $("#login .message[for=passwd]").text("服务端出现异常,请稍后重试");
else {
var s = new JSEncrypt;
s.setPublicKey(i.key), a = s.encrypt(i.hash + a), $.post("/ajax/miniLogin/login", {
userid: t,
pwd: a,
captcha: n,
keep: r
}, function(t) {
if (!t.status) {
var a = t.message.code;
if (-105 == a) {
var n = $("#login .captcha-row");
n.is(":visible") ? n.children(".input").addClass("error").next().text(ERROR_MAP[a]) : n.slideDown(), refresh_captcha(n.find(".captcha-img"))
} else -626 == a || -652 == a ? $("#login .uname-row").children(".input").addClass("error").next().text(ERROR_MAP[a]) : $("#login .passwd-row").children(".input").addClass("error").next().text(ERROR_MAP[a]);
return void e.removeClass("loading")
}
window.location.href = t.data.crossDomain
}, "json")
}
})
}
}), $("#login").on("keyup", "input", function(e) {
$(this).closest(".input").removeClass("error ok").next().text(""), 13 == e.keyCode && $("#login-submit").click()
})
}
public static string PemToXml(string pem)
{
if (pem.StartsWith("-----BEGIN PUBLIC KEY-----"))
{
//pem = pem.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "");
return GetXmlRsaKey(pem, obj =>
{
var publicKey = (RsaKeyParameters)obj;
return DotNetUtilities.ToRSA(publicKey);
}, rsa => rsa.ToXmlString(false));
}
throw new InvalidKeyException("Unsupported PEM format...");
}
private static string GetXmlRsaKey(string pem, Func<object, RSA> getRsa, Func<RSA, string> getKey)
{
using (var ms = new MemoryStream())
using (var sw = new StreamWriter(ms))
using (var sr = new StreamReader(ms))
{
sw.Write(pem);
sw.Flush();
ms.Position = 0;
var pr = new Org.BouncyCastle.OpenSsl.PemReader(sr);
object keyPair = pr.ReadObject();
using (RSA rsa = getRsa(keyPair))
{
var xml = getKey(rsa);
return xml;
}
}
}
/// <summary>
/// RSA加密
/// </summary>
/// <param name="publickey"></param>
/// <param name="content"></param>
/// <returns></returns>
public static string RSAEncrypt(string publickey, string content)
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
byte[] cipherbytes;
rsa.FromXmlString(publickey);
cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false);
return Convert.ToBase64String(cipherbytes);
}
大概逻辑为把从服务器上获取的公钥用 Org.BouncyCastle.OpenSsl.PemReader 和 DotNetUtilities.ToRSA 转换成 RSACryptoServiceProvider 可用的 xml 格式公钥,然后对 (hash+密码 ) 字符串进行加密,再POST到服务器,可是这样有时候可以成功登录,大部分时候返回 "-627": "密码错误"
因为对RSA加密算法不太了解,只能判断出加密的密码在服务器解密出来的结果不对,希望能得到这方面的指点,C#端应该怎么修改,非常感谢。