Unable to obtain public key for StrongNameKeyPair

北城以北 提交于 2020-01-01 10:02:04

问题


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.


回答1:


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.




回答2:


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!




回答3:


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.




回答4:


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.



来源:https://stackoverflow.com/questions/5659740/unable-to-obtain-public-key-for-strongnamekeypair

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!