如何导出AWS签名版本4(在ColdFusion中)的登录密钥? [英] How to derive a sign-in key for AWS Signature Version 4 (in ColdFusion)?

查看:217
本文介绍了如何导出AWS签名版本4(在ColdFusion中)的登录密钥?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用ColdFusion来访问亚马逊网络服务(AWS)使用他们当前的身份验证方法称为签名版本4.我已参阅他们的文档,其中包含代码示例几种编程语言,以及其他语言。他们提供了一些测试输入值,以传递到我的脚本的签名函数,以及一些预期的结果。

I am trying to use ColdFusion to access Amazon Web Services (AWS) using their current authentication method known as Signature Version 4. I have consulted their documentation which has code examples for several programming languages, as well as pseudo-code for other languages. They provided some test input values to pass in to my script's signature function, and also some expected results.

这里是测试输入:

key = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY'
dateStamp = '20120215'
regionName = 'us-east-1'
serviceName = 'iam'

以下是预期结果:

kSecret  = '41575334774a616c725855746e46454d492f4b374d44454e472b62507852666943594558414d504c454b4559'
kDate    = '969fbb94feb542b71ede6f87fe4d5fa29c789342b0f407474670f0c2489e0a0d'
kRegion  = '69daa0209cd9c5ff5c8ced464a696fd4252e981430b10e3d3fd8e2f197d7a70c'
kService = 'f72cfd46f26bc4643f06a11eabb6c0ba18780c19a8da0c31ace671265e3c87fa'
kSigning = 'f4780e2d9f65fa895f9c67b32ce1baf0b0d8a43505a000a1a9e090d414db404d'

kSigning的正确值应为:

The correct value for "kSigning" should be this:

f4780e2d9f65fa895f9c67b32ce1baf0b0d8a43505a000a1a9e090d414db404d

但是,对于kSigning,我的代码生成:

However, for "kSigning" my code generates this:

31A84DCE0538A8B15ED68CCFBD803F17947E41BF625EFFD1AD6A67FC821F9BE2

我使用Railo 4.2。有人可以帮我解决这个问题,以便预期的值匹配转储的值吗?这是我的ColdFusion标记:

I am using Railo 4.2. Can someone please help me solve this, so that the anticipated value matches the dumped value? Here's my ColdFusion markup:

<cfsilent>

<!--- HMACSHA256 --->
<cffunction name="sign" returntype="binary" access="private" output="false" hint="Sign with NSA SHA-256 Algorithm">
   <cfargument name="signMessage" type="string" required="true" />
   <cfargument name="signKey" type="string" required="true" />

   <cfset var jMsg = JavaCast("string",arguments.signMessage).getBytes("utf-8") />
   <cfset var jKey = JavaCast("string",arguments.signKey).getBytes("utf-8") />
   <cfset var key = createObject("java","javax.crypto.spec.SecretKeySpec") />
   <cfset var mac = createObject("java","javax.crypto.Mac") />

   <cfset key = key.init(jKey,"HmacSHA256") />
   <cfset mac = mac.getInstance(key.getAlgorithm()) />
   <cfset mac.init(key) />

   <cfreturn mac.doFinal(jMsg) />
</cffunction>

<!--- Get Signature Key --->
<cffunction name="getSignatureKey" returntype="binary" access="private" output="false" hint="Derive the sign-in key">
    <cfargument name="key" type="string" required="true" />
    <cfargument name="dateStamp" type="string" required="true" />
    <cfargument name="regionName" type="string" required="true" />
    <cfargument name="serviceName" type="string" required="true" />

    <cfset var kSecret = "AWS4" & arguments.key />
    <cfset var kDate = sign( arguments.dateStamp, kSecret ) />
    <cfset var kRegion = sign( arguments.regionName, kDate ) />
    <cfset var kService = sign( arguments.serviceName, kRegion ) />
    <cfset var kSigning = sign( arguments.serviceName, kService ) />

    <cfreturn kSigning />
</cffunction>

</cfsilent><!doctype html>

<html lang="en">
<head>
    <meta charset="utf-8">
    <title>AWS Test</title>
</head>
<body>

<cfset kSecret = getSignatureKey( 
    'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY', 
    '20120215', 
    'us-east-1', 
    'iam' 
) />
<cfdump var="#BinaryEncode(kSecret, 'hex')#" label="kSecret" />

</body>
</html>


推荐答案


< cfset var kRegion = sign(arguments.regionName,kDate)/>



很少意外的代码运行没有错误,因为 sign()函数期望两个字符串,但代码实际上是传递一个字节数组的第二个参数。 (在CF11下它抛出一个错误)。也许有一些隐式转换?
无论如何,在重构函数后,该示例工作正常,有一个异常。该示例的最后一行使用文本字符串aws4_request,而不是arguments.serviceName。请参阅下面的示例。

I am little surprised the code runs without error, as the sign() function expects two strings, but the code is actually passing in a byte array for the second parameter. (Under CF11 it throws an error). Perhaps there is some sort of implicit conversion going on? Anyway, after refactoring the functions slightly, the example worked fine with one exception. The very last line of the example uses the literal string "aws4_request" rather than "arguments.serviceName". See example below.

说到这里,不是Railo有一个HMAC功能,你可以使用,而不是滚动自己的?我猜这样,作为 HMAC() 包含在CF10 +中。 更新:作为 vrtjason在注释中注明,Railo在 HMAC() com / getrailo / railo / commit / f36bd5c72c3dc084b08aab9edeabba43f5a7548brel =nofollow> 4.0.0.011 。但是,为了向后兼容,下面的java版本应该与大多数任何版本配合使用。

Having said that, does not Railo have an HMAC function you can use rather than rolling your own? I am guessing so, as HMAC() is included in CF10+. Update: As vrtjason noted in the comments, Railo added the HMAC() function in 4.0.0.011. However, for backward compatibility the java version below should work with most any version.

示例:

result = getSignatureKey(key, dateStamp, regionName, serviceName);
writeDump( binaryEncode(result, "hex") );

结果

F4780E2D9F65FA895F9C67B32CE1BAF0B0D8A43505A000A1A9E090D414DB404D 

功能:

<cffunction name="getSignatureKey" returntype="binary" access="private" output="false" hint="Derive the sign-in key">
    <cfargument name="key" type="string" required="true" />
    <cfargument name="dateStamp" type="string" required="true" />
    <cfargument name="regionName" type="string" required="true" />
    <cfargument name="serviceName" type="string" required="true" />

    <cfset Local.kSecret = charsetDecode("AWS4" & arguments.key, "UTF-8") />
    <cfset Local.kDate = sign( arguments.dateStamp, Local.kSecret ) />
    <cfset Local.kRegion = sign( arguments.regionName, Local.kDate ) />
    <cfset Local.kService = sign( arguments.serviceName, Local.kRegion ) />
    <cfset Local.kSigning = sign( "aws4_request", Local.kService ) />

    <cfreturn Local.kSigning />
</cffunction>




<cffunction name="sign" returntype="binary" access="private" output="false" hint="Sign with NSA SHA-256 Algorithm">
   <cfargument name="message" type="string" required="true" />
   <cfargument name="key" type="binary" required="true" />
   <cfargument name="algorithm" type="string" default="HmacSHA256" />
   <cfargument name="encoding" type="string" default="UTF-8" />

   <cfset Local.keySpec = createObject("java","javax.crypto.spec.SecretKeySpec") />
   <cfset Local.keySpec = Local.keySpec.init( arguments.key, arguments.algorithm ) />
   <cfset Local.mac = createObject("java","javax.crypto.Mac").getInstance( arguments.algorithm ) />
   <cfset Local.mac.init( Local.keySpec ) />

   <cfreturn Local.mac.doFinal( charsetDecode(arguments.message, arguments.encoding ) ) />
</cffunction>

这篇关于如何导出AWS签名版本4(在ColdFusion中)的登录密钥?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆