Unable to obtain public key for StrongNameKeyPair

2020-07-10 09:47发布

I have ported developing to another computer and if i run project, i have this exception:

Unable to obtain public key for StrongNameKeyPair.

HibernateException: Creating a proxy instance failed

On original computer it works OK without problems.

I found on google that it is problem with some crypting and I should try "sn -m n", by I don't know how. sn.exe is in more folders, i tryed some run from command line but it writes:

Failed to open registry key -- Unable to format error message 00000005

I don't know if problem is because NHibernate or not, there are more similar whitch dialogs and it throw this exception only in one case.

there is part of code whitch throw exception:

public IList<DTO> GetAll(GridSortOptions sortOptions, DTOListModel<DTO> listModel)
{
    return GetAllCriteria(sortOptions, CreateCriteria(), listModel).List<DTO>();
}

No one project from solution use signing. I don't understand what exactly this errors means and what i should look for.

4条回答
冷血范
2楼-- · 2020-07-10 10:01

For anyone else who comes across this, I just had the same exception, on a physical machine. Nothing changed overnight, but this exception started presenting in the morning.

Turned out to be low disk space issue, and the dynamic proxy assemblies couldn't be written to disk. Only realised this because I happened to notice the Windows 'low disk space' icon when it appeared briefly. :-P

Clearing out a bunch of (big) temp files made the problem go away.

查看更多
祖国的老花朵
3楼-- · 2020-07-10 10:03

I had the same issue today and didn't like the provided solutions. These were:

  • Having your own version of Castle.Core with the strong naming code removed. Reference
  • Modifying permissions on the folder. Reference: This question
  • Changing the crypto key storage. Reference: This question

The following may be a dirty hack but it works quite well and I don't have to explain to IT why I want all of the end users computers reconfigured.

/// <summary>
/// Ensures that NHibernate creates no strong named proxy assemblies.
/// Assumes usage of Castle.DynamicProxy. Needs to be revisited
/// after update of NHibernate or Castle.Proxy!
/// </summary>
private static void EnsureNHibernateCreatesNoStrongNamedProxyAssemblies()
{
    if (!StrongNameUtil.CanStrongNameAssembly)
    {
        Logger.Debug("NHibernate is not trying to strong name assemblies." +
                     "No action needed.");
        return;
    }

    const string FieldName = "canStrongNameAssembly";
    var type = typeof(StrongNameUtil);
    var field = type.GetField(FieldName, BindingFlags.Static
                                         | BindingFlags.NonPublic);
    if (field == null)
    {
        Logger.Warn(
            "No field with the name {0} exists in the type {1}."
            + "Can't change NHibernate to use weak named proxy assemblies.", 
            FieldName, type);
        return;
    }

    field.SetValue(null, false);

    if (StrongNameUtil.CanStrongNameAssembly)
    {
        Logger.Warn(
            "Couldn't change value of field {0} on type {1}. "
            + "NHibernate will continue to use strong named proxy assemblies.", 
            FieldName, type);
    }
    else
        Logger.Debug("Successfully changed NHibernate to use "
                     + "weak named proxy assemblies.");
}

Just make sure you call this method at the very beginning of your program before the first proxy is generated.

I guess the real solution would be to upgrade to NHibernate 3.3 which suppesdly doesn't have this problem anymore, but that's not an option right now.

查看更多
SAY GOODBYE
4楼-- · 2020-07-10 10:05

NHibernate is dynamically creating .NET assemblies (dynaic proxies) and needs to sign them. By default the Windows OS configures the crypto key storage to be machine level and stores the keys in C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys. Most likely your user can create (for example) a text file in this folder, but not delete it because you do not have full control.

Your options are

  1. Get full control of C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys by modifying permissions which might not be recommended.

  2. Change your crypto key storage to user level by running the "sn.exe -m n" from the Windows SDK. http://msdn.microsoft.com/en-us/library/k5b5tt23(v=VS.90).aspx This will put crypto key stores under under your users local profile which you should always have full contorl to.

There are several articles online that describe a similar problem. For example, see http://support.targetprocess.com/Default.aspx?g=posts&t=305.

查看更多
\"骚年 ilove
5楼-- · 2020-07-10 10:24

Had a similar issue today with a different use case (a .NET service running on a W2008R2 box) but exactly the same error.

Using procmon I traced it back to a failed write on a key in C:/ProgramData/Microsoft/Crypto/RSA/MachineKeys.

Following the guidance to add EVERYONE with special permissions on the folder as noted here fixed the problem: http://toastergremlin.com/?p=432

Also, make sure you add EVERYONE @ local machine and not EVERYONE @ your domain!

查看更多
登录 后发表回答