求助,C# RSA加密发送到服务器,返回密码错误
1、从 "/login?act=getkey&_=" + (new Date).getTime() 获得公钥和hash值,返回的结果类似:
{
"hash" : "52c17e7b60a06c5b",
"key" : "-----BEGIN PUBLIC KEY-----\nMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANe7Rmtt4U3mjPwixdxLrw9Yczkht8VE\nxECb05iKTGrlXcc3vXuDla1Vjs7EY2xD4se+pAaICeSqS+Rq7yVZKkcCAwEAAQ==\n-----END PUBLIC KEY-----\n"
}其中的hash值会和密码字符串连接,然后加密。页面RSA加密采用的是jsencrypt,地址为 http://travistidwell.com/jsencrypt/ ,关键代码为:
var s = new JSEncrypt;
s.setPublicKey(i.key), // i为上述json
a = s.encrypt(i.hash + a), // a为密码最后得到的a为加密的密码。2、POST登录数据到 /ajax/miniLogin/login ,POST的数据格式为:
userid=用户名&pwd=加密的密码&captcha=验证码&keep=1
使用Cookie中的sid值确定客户端。
POST完成后会返回一个json数据,错误信息如下:
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()
})
}对密码学不是很懂,C#采用的加密函数为:
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#端应该怎么修改,非常感谢。相关推荐
RSA非对称 C#解密、js加密实现登陆密文传输
RSA非对称 C#解密、js加密实现登陆密文,传输RSA非对称 C#解密、js加密实现登陆密文传输,RSA非对称 C#解密、js加密实现登陆密文传输
跨平台RSA加密解密技术指南:JavaScript与C#实现
RSA加密算法是目前广泛使用的一种非对称加密技术。与传统的对称加密不同,非对称加密使用一对密钥——公钥和私钥。公钥是公开的,可以广泛分发用于加密信息,而私钥必须保密,用于解密由对应公钥加密的信息。这种机制确保了只有持有正确私钥的接收方才能解密信息,为数据传输提供了强大的安全保障。类位于的命名空间中,它提供了基于RSA算法的公钥加密服务。该类是实现RSA解密的核心组件,它允许开发者使用私钥对数据进行解密操作。
跨平台RSA加密解密实战:JS、C#、Java三端兼容方案与避坑指南
非对称加密是保障数据传输安全的核心技术之一,其核心原理是使用一对密钥(公钥和私钥)分别进行加密和解密操作,从而解决了对称加密中密钥分发的难题。RSA作为最经典的非对称加密算法,在跨平台、跨语言场景中具有重要技术价值,尤其适用于前端加密、后端解密的典型安全需求,如登录认证、支付令牌保护等。然而,不同编程语言对RSA的实现细节存在差异,导致互操作性成为工程实践中的主要挑战。本文聚焦于解决JS、C#、Java三端在RSA加密解密过程中的兼容性问题,通过统一密钥格式(PEM)、填充方案(RSA-OAEP)和数据编码
同时兼容JS和C#的RSA加密解密算法详解(对web提交的数据加密传输)
主要给大家介绍了关于同时兼容JS和C#的RSA加密解密算法,通过该算法可以对web提交的数据进行加密传输,文中通过图文及示例代码介绍的非常详细,需要的朋友们可以参考借鉴,下面来一起看看吧。
C# RSA 加密,压缩,并通过SFTP上传实例
使用C#编写的 压缩文件 使用RSA 并自动上传到SFTP的代码示例 在VS2017上编写 依赖于Ionic.Zip.dll 和 Renci.SshNet.dll


