使用X509证书进行RSA加密和解密2

问题描述 投票:0回答:2

所以,我接下来需要的是:

  1. 创建开发证书,为客户端获取一份证书,为服务器获取一份证书
  2. 通过客户端编码的 API 检索密码并在服务器上解码

现在,我成功地按照此链接创建了证书。那里的女孩一步步指导如何获得自签名证书,将它们存放在商店等等......现在,我遇到问题的部分:

我已成功使用此代码加密我的数据:

public static string Encrypt(string stringForEncription, string PathToPrivateKey)
    {
        X509Certificate2 myCertificate;
        try
        {
            myCertificate = new X509Certificate2(PathToPrivateKey, "Test123");
        }
        catch (Exception e)
        {
            throw new CryptographicException("Unable to open key file.");
        }

        RSACryptoServiceProvider rsaObj;
        if (myCertificate.HasPrivateKey)
        {
            rsaObj = (RSACryptoServiceProvider)myCertificate.PrivateKey;
        }
        else
            throw new CryptographicException("Private key not contained within certificate.");

        if (rsaObj == null)
            return String.Empty;

        byte[] decryptedBytes;
        byte[] array = Encoding.UTF8.GetBytes(stringForEncription);
        try
        {
            decryptedBytes = rsaObj.Encrypt(array, false);
            //decryptedBytes = rsaObj.Encrypt(Convert.FromBase64String(Base64EncryptedData), false);
        }
        catch (Exception e)
        {
            throw new CryptographicException("Unable to encrypt data.");
        }

        //    Check to make sure we decrpyted the string 
        if (decryptedBytes.Length == 0)
            return String.Empty;
        else
            return System.Text.Encoding.UTF8.GetString(decryptedBytes);
    }

对于 PathToPrivate 键变量,我使用客户端 ClientCert.pfx 的路径。我不知道是否应该使用其他的,但这是包含我制作的所有证书的文件夹的快照:

现在,为了解密,我使用下一个代码:

 public static string DecryptEncryptedData(string Base64EncryptedData, string PathToPrivateKey)
    {
        X509Certificate2 myCertificate;
        try
        {
            myCertificate = new X509Certificate2(PathToPrivateKey, "Test123");
        }
        catch (Exception e)
        {
            throw new CryptographicException("Unable to open key file.");
        }

        RSACryptoServiceProvider rsaObj;
        if (myCertificate.HasPrivateKey)
        {
            rsaObj = (RSACryptoServiceProvider)myCertificate.PrivateKey;
        }
        else
            throw new CryptographicException("Private key not contained within certificate.");

        if (rsaObj == null)
            return String.Empty;

        byte[] decryptedBytes;
        try
        {
            decryptedBytes = rsaObj.Decrypt(Convert.FromBase64String(Base64EncryptedData), false);
        }
        catch (Exception e)
        {
            throw new CryptographicException("Unable to decrypt data.");
        }

        //    Check to make sure we decrpyted the string 
        if (decryptedBytes.Length == 0)
            return String.Empty;
        else
            return System.Text.Encoding.UTF8.GetString(decryptedBytes);
    }

无论我尝试做什么,它都会给我例外:

{"The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters. "}

非常感谢有人帮助我。

c# security encryption rsa x509certificate2
2个回答
0
投票

您收到错误的原因是您尝试从实际上不是 Base-64 字符串的值

Convert.FromBase64String
得到的字符串。

加密数据后,您应该将字节数组转换为 Base-64 字符串。 为此,请使用 Convert.ToBase64String

return Convert.ToBase64String(decryptedBytes);

然后你的解密行就可以工作了:

解密字节= rsaObj.Decrypt(Convert.FromBase64String(Base64EncryptedData), false);


0
投票

这不是您所期望的确切答案,但我写在这里是因为它作为评论太长了。

我认为解密本身根本没有问题(我找到了您使用php加密的代码的示例博客)这就是为什么我评论说我对解密目标的加密字符串感到好奇。

我也花了几个月的时间努力理解安全性,现在我一起使用对称(AES)和非对称(RSA)。理解真的很重要,每个人都需要时间..

RSA 是非对称且单向的,这意味着只能通过公钥进行加密,而只能通过私钥进行解密。 您在加密方法中使用私钥,它似乎只是从解密中复制的。

Zesty 的答案仅在格式方面是正确的。您还需要了解格式。我们需要Convert.ToBase64String和Convert.FromBase64String来加密和解密从字节到base64string,反之亦然。然而这个base64字符串不仅仅是像'hello'那样简单,而是 'SABlAGwAbABvACAAVwBvAHIAbABkAA==' 如您所见这里

我强烈建议使用完整的解决方案(而不是像 php 加密那样的一半),就像这样博客,以便加密和解密以及所有内容协调一致。

正如我最后评论的那样,如果加密是从客户端完成的并且您没有只有好的用户,您需要考虑如何防止黑人用户。

我希望我的经验有助于理解最重要的安全性。

© www.soinside.com 2019 - 2024. All rights reserved.