在本部分,您将学习如何创建和使用强名称程序集,连同 Javascript 一起,与自定义的后端进行交互。
信任链 (Chain of Trust) 系统允许外部互联网应用程序信任源于 Unity 网络播放器 (Web Player) 的请求。如果希望为 Unity 开发人员在 Unity 网络播放器 (Web Player) 中创建游戏提供全功能 API,这点会比较有用。如需使用信任链 (Chain of Trust) 系统,必须拥有某种接受请求的互联网应用程序后端,最常见的是带 REST API 的网络应用程序。还要有一个托管 C# (Managed C#) 程序集,包含调用互联网应用程序的代码。
建立信任链的第一步是创建程序集签名所需的加密密匙对。在 Windows、OS X 或 Linux 系统上使用 SN 工具进行。
- 要创建一个新密匙对,请打开命令行终端和类型: sn -k myNewKey.snk
- 将 myNewKey.snk 替换为想要的密匙对文件名。从信任链 (Chain of Trust) 系统的角度来说,文件名无关紧要。
- 保证 .SNK 文件的安全!如果该文件泄密,恶意开发人员会欺骗您的程序集。
程序集签名
接着针对托管 C# (Managed C#) 程序集(将用于调用后端),使用生成的密匙对进行签署。需要用到 Windows、OS X 和 Linux 系统中随附的 al 工具。
程序集签名的过程非常简单。
- 打开命令行终端,导航至托管 C# (Managed C#) 程序集和类型: al /out:mySignedAssembly.dll myUnsignedAssembly.dll /keyfile:myNewSky.snk
- mySignedAssembly.dll 是程序集的最终所需名称。
- myUnsignedAssembly.dll 是一般未签名的托管 C# (Managed C#) 程序集的名称。
- myNewKey.snk 是加密密匙对文件的名称。
- 一旦 al 结束运行,签署的程序集将准备就绪。将其放到 Unity 工程中,与信任链 (Chain of Trust) 系统一起使用。
注入机密
可在 Unity 游戏加载完成后随时在 Unity 网络播放器 (Web Player) 中放入机密。该步骤通过暴露于 UnityObject2 Javascript 对象中的 Javascript SendMessage 函数完成。
向某游戏对象传递一条特殊格式的消息时,信任链 (Chain of Trust) 系统检测到您想注入的机密并拦截消息。无需创建或重命名任何游戏对象就可以使用该系统。有了一个名为 u 的 UnityObject2 实例,Javascript 调用即为:
u.GetUnity().SendMessage(“ChainOfTrust_SetValueASDF”, “.”, “name=mySecretDataName;value=mySecretValue;publickey=publicKeyTokenOfMyAssembly”);
SendMessage 函数类似于标准的 MonoBehaviour/SendMessage 函数。它带有三个名义参数:
目标游戏对象的名称,调用方法的名称,以及一个字符串参数。
有了信任链 (Chain of Trust) 系统,方法名称完全被忽略。目标游戏对象的名称必须以 ChainOfTrust_SetValue 开头,ChainOfTrust_SetValue 后的任何字符会被安全忽略。
字符串参数的格式非常重要。信任链 (Chain of Trust) 系统会将其分成三部分,以分号区隔。分别为:
名称 (name),
值 (value)以及
公匙 (publickey)。
注意大写!这三个关键字都必须是小写,后面加等号 (=)。
可以给机密资料加上任何名称 (name)。替换上例中的 mySecretDataName 即可。
值 (value)是共享密匙,或希望保存在信任链 (Chain of Trust) 系统中的其他机密资料。准确的说,该值所含内容具体针对特定应用程序。替换上例中的 mySecretDataValue 即可。
公匙 (publickey) 是用来签署托管 C# (Managed C#) 程序集的公匙标记。利用 sn 工具可以在签署的程序集中找到: sn -T mySignedAssembly.dll 复制整个公匙标记,前后不带空格,并替换上例中的 myPublicKeyToken。
在虚拟游戏对象 (Virtual Game Object) 的名称中加上随机数据。无法保证每位网络播放器 (Web Player) 用户都运行最新版网络播放器 (Web Player),这就意味着并非所有网络播放器 (Web Player) 都会拦截 SendMessage 调用。如果恶意开发人员关注您的 Javascript 并看到虚拟游戏对象的名称和正在使用的函数,他们可能会创建一个 Unity 游戏,包含带该名称的游戏对象并执行该方法。在非常特殊的情况下,如果恶意开发人员的代码在旧版网络播放器 (Web Player) 上运行,那么其代码会拦截您的共享机密,以对您的后端进行不需要的调用。对游戏对象进行随机命名,使得在较旧版本上运行时他人难以拦截您的信任链 (Chain of Trust) 调用。
取回机密
一旦机密注入到 Unity 网络播放器 (Web Player) 中,就只能通过用匹配的公匙标记加密签署的(“强命名”)托管 C# (Managed C#) 程序集来取回。
托管 C# (Managed C#) 程序集必须调用 Security.GetChainOfTrustValue 来取回机密。GetChainOfTrustValue 要求您在机密名称中传递
如注入时在有效负载的 name= 子句中指定的那样。
GetChainOfTrustValue 以文本字符的形式返回机密值,然后可用于程序集中。
对于注入有效负载 name=mySecret;value=superSecretData;publickey=A92181sn828O,取回托管 C# (Managed C#) 程序集中机密的代码为: string myValue = Security.GetChainOfTrustValue(“mySecret”);
经历过保护机密值安全的许多问题后,不应将机密值返回到任何函数或托管 C# (Managed C#) 程序集之外的代码中。
只要是试图从不在签署程序集内的代码或签名与机密指定的公匙不匹配的签署程序集中调用 Security.GetChainOfTrustValue,就会在日志中生成一个错误,Security.GetChainOfTrustValue 将返回空字符串。