【问题标题】:RSA encryption stopped working when server was joined to domain当服务器加入域时,RSA 加密停止工作
【发布时间】:2017-11-22 15:51:11
【问题描述】:

我有一个有效的 RSA 加密,基本上是这样创建的

public string DecryptFormula( byte[] WholeData )
{
    // Get from container the key used to encrypt entropy bytes 
    RSAParameters PublicKey = GetKeyFromContainer("CorroredKeys");

    byte[] KeyLengthByte = new byte[4];
    Array.Copy(WholeData, KeyLengthByte, 4);
    int KeyLength = BitConverter.ToInt32(KeyLengthByte, 0);
    // Encrypt entropy
    byte[] encryptedKey = new byte[KeyLength];
    Array.Copy(WholeData, 4, encryptedKey, 0, KeyLength);

    //Pass the data to ENCRYPT, the public key information  
    //(using RSACryptoServiceProvider.ExportParameters(false), 
    //and a boolean flag specifying no OAEP padding.
    byte[] PrivateKey = RSADecrypt(encryptedKey, PublicKey, false);
    ...
}
    static public byte[] RSADecrypt(byte[] DataToDecrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)
    {
        try
        {
            byte[] decryptedData;
            //Create a new instance of RSACryptoServiceProvider. 
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
            {
                //Import the RSA Key information. This needs 
                //to include the private key information.
                RSA.ImportParameters(RSAKeyInfo);

                //Decrypt the passed byte array and specify OAEP padding.   
                //OAEP padding is only available on Microsoft Windows XP or 
                //later.  
                decryptedData = RSA.Decrypt(DataToDecrypt, DoOAEPPadding);
            }
            return decryptedData;
        }
        //Catch and display a CryptographicException   
        //to the console. 
        catch (CryptographicException ex)
        {             
            return null;
        }

    }

但是,在将运行此代码的服务器加入到域后,解密突然停止工作。到目前为止,我已经对此进行了调试,发现问题似乎出在

RSA.Decrypt(DataToDecrypt, DoOAEPPadding)

给出一个例外

System.Security.Cryptography.CryptographicException:参数不正确。

在 System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 小时)

在 System.Security.Cryptography.RSACryptoServiceProvider.DecryptKey(SafeKeyHandle pKeyContext, Byte[] pbEncryptedKey, Int32 cbEncryptedKey, Boolean fOAEP, ObjectHandleOnStack ohRetDecryptedKey)

在 System.Security.Cryptography.RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)

在 MyCalculation.ProjectBase.RSADecrypt(Byte[] DataToDecrypt, RSAParameters RSAKeyInfo, Boolean DoOAEPPadding)

如何进行此操作以及在哪里寻找可能的原因?注意:此代码在服务器加入域之前运行。

编辑: Alex K. 询问我使用的密钥容器是否为空。这也是我怀疑的。但是,至少我的公钥的 Modulus 字段有一些数据。我无法在生产环境中运行调试器,但我编写了一些将字节数组写入日志文件的代码。

RSAParameters PublicKey = GetKeyFromContainer("CorroredKeys");
WriteLog("PublicKey, modulus: " + BytesToString(PublicKey.Modulus));

仅供参考,公钥是这样生成的:

    public static RSAParameters GenKey_SaveInContainer(string ContainerName)
    {

        // First, to get a fresh key, delete the key from the container.
        DeleteKeyFromContainer(ContainerName);

        // Create the CspParameters object and set the key container 
        // name used to store the RSA key pair.
        CspParameters cp = new CspParameters();
        cp.KeyContainerName = ContainerName;


        // Create a new instance of RSACryptoServiceProvider that accesses
        // the key container MyKeyContainerName and generates new public and private key data
        using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(cp))
        {
            byte[] Keyblob = RSA.ExportCspBlob(true);
            // Return saved key information to the caller
            return RSA.ExportParameters(false);
        }
    }


    /// <summary>
    /// Clears and deletes an asymmetric key pair from given key container
    /// </summary>
    /// <param name="ContainerName">Key container name where RSA key pair is saved</param>
    public static void DeleteKeyFromContainer(string ContainerName)
    {
        // Create the CspParameters object and set the key container 
        // name used to store the RSA key pair.
        CspParameters cp = new CspParameters();
        cp.KeyContainerName = ContainerName;

        // Create a new instance of RSACryptoServiceProvider that accesses
        // the key container.
        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);

        // Delete the key entry in the container.
        rsa.PersistKeyInCsp = false;

        // Call Clear to release resources and delete the key from the container.
        rsa.Clear();

    }

这样从容器中读取密钥:

public static RSAParameters GetKeyFromContainer(string ContainerName)
{
    // Create the CspParameters object and set the key container 
    // name used to store the RSA key pair.
    CspParameters cp = new CspParameters();
    cp.KeyContainerName = ContainerName;

    // Create a new instance of RSACryptoServiceProvider that accesses
    // the key container MyKeyContainerName.

    using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(cp))
    {
        // Return saved key information to the caller
        return RSA.ExportParameters(true);
    }
}

【问题讨论】:

  • 如果您使用用户级密钥容器并以域用户身份登录,那么您将拥有不同的配置文件,因此您将拥有不同的(空)密钥容器,是这种情况吗?

标签: c# encryption cryptography rsa


【解决方案1】:

问题在于,在将服务器加入域后,对数据进行编码和解码的两个进程在两个不同的用户 ID 上运行。当这被纠正并且数据首先被再次编码时,编码的数据可以被再次解码。

这是一个非常愚蠢的案例,我应该立即发现这一点。经验教训:永远不要相信设置会保持原样。

【讨论】:

    猜你喜欢
    • 2015-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-14
    • 1970-01-01
    • 2013-07-23
    • 1970-01-01
    相关资源
    最近更新 更多