Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/251.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
来自PHP&;的错误SHA1;CF根据AmazonS3_Php_Coldfusion_Amazon S3_Hmacsha1 - Fatal编程技术网

来自PHP&;的错误SHA1;CF根据AmazonS3

来自PHP&;的错误SHA1;CF根据AmazonS3,php,coldfusion,amazon-s3,hmacsha1,Php,Coldfusion,Amazon S3,Hmacsha1,Amazon始终生成与PHP或CF不同的哈希,这会导致持久的“SignatureDesNotMatch”错误 根据,GET请求[不带REST头]的签名如下: Signature = URL-Encode( Base64( HMAC-SHA1( SecretAccessKey, UTF-8-Encoding-Of( StringToSign ) ) ) ); StringToSign = HTTP-VERB + "\n" + Content-MD5 + "\n" + Conten

Amazon始终生成与PHP或CF不同的哈希,这会导致持久的“SignatureDesNotMatch”错误

根据,GET请求[不带REST头]的签名如下:

Signature = URL-Encode( Base64( HMAC-SHA1( SecretAccessKey, UTF-8-Encoding-Of( StringToSign ) ) ) );

StringToSign = HTTP-VERB + "\n" +
    Content-MD5 + "\n" +
    Content-Type + "\n" +
    Expires + "\n" +
    CanonicalizedAmzHeaders +
    CanonicalizedResource; 
示例数据:

  • 秘书访问键:wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
  • Content-MD5和内容类型:(可选-跳过)
  • CanonicalizeDamzheader:(无标题-跳过)
  • 资源:johnsmith.s3.amazonaws.com/photos/puppy.jpg
  • CanonicalizedResource:/johnsmith/photos/puppy.jpg
提供了两个示例:

  • 过期1175139620;签名:rucSbH0yNEcP9oM2XNlouVI3BH4%3D
  • 到期日1141889120;签名:vjbyPxybdZaNmGa%2byt272yeav4%3D
  • 要从中重新创建此(CFHMAC):

    //PHP
    $expires=1175139620;
    $SecretAccessKey=“wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY”;
    $StringToSign=“GET\n\n\n$expires\n/johnsmith/photos/puppy.jpg”;
    $signature=urlencode(base64_编码(hash_hmac('sha1',utf8_编码($StringToSign),$SecretAccessKey,true));
    //冷饮
    
    但两种语言返回的$signature为:

  • 过期1175139620;签名:NpgCjnDzrM%2BWFzoENXmpNDUsSn8%3D
  • 到期日1141889120;签名:fScKGHCDI0NY5E7CYp9Vc8VKMbY%3D
  • 我们已经注意到其他人提到的这些问题:

  • hash_mac有第三个参数raw,必须设置为true
  • S3 psuedocode中stringToSign和key的顺序应颠倒
  • 整个stringToSign必须在一行上(以免创建额外的换行符)
  • 编辑:根据Leigh的回答更新CF代码中的换行符;现在CF与PHP匹配

    我显然做错了什么,但不知道是什么。
    [我听到有人打趣说AmazonS3会被称为CSS——“复杂的存储服务”,但这个名字已经被取下来了!]

    救命啊

    这有帮助吗

    <cffunction name="getRequestSignature" access="private" output="false" returntype="string">
        <cfargument name="verb" type="string" required="true" />
        <cfargument name="bucket" type="string" required="true" />
        <cfargument name="objectKey" type="string" required="true" />
        <cfargument name="dateOrExpiration" type="string" required="true" />
        <cfargument name="contentType" type="string" default="" />
        <cfargument name="contentMd5" type="string" default="" />
        <cfargument name="canonicalizedAmzHeaders" type="string" default=""
            hint="A newline-delimited list of headers, in lexographical order, duplicates collapsed, and no extraneous whitespace.  See Amazon's description of 'CanonicalizedAmzHeaders' for specifics." />
        <cfscript>
            var stringToSign = "";
            var algo = "HmacSHA1";
            var signingKey = "";
            var mac = "";
            var signature = "";
    
            stringToSign = uCase(verb) & chr(10)
                & contentMd5 & chr(10)
                & contentType & chr(10)
                & dateOrExpiration & chr(10)
                & iif(len(canonicalizedAmzHeaders) GT 0, de(canonicalizedAmzHeaders & chr(10)), de(''))
                & "/" & listAppend(bucket, objectKey, "/");
            signingKey = createObject("java", "javax.crypto.spec.SecretKeySpec").init(variables.awsSecret.getBytes(), algo);
            mac = createObject("java", "javax.crypto.Mac").getInstance(algo);
            mac.init(signingKey);
            signature = toBase64(mac.doFinal(stringToSign.getBytes()));
    
            return signature;
        </cfscript>
    </cffunction>
    
    
    var stringToSign=“”;
    var algo=“HmacSHA1”;
    var signingKey=“”;
    var mac=“”;
    var签名=”;
    stringToSign=uCase(动词)和chr(10)
    &内容MD5和chr(10)
    &contentType和chr(10)
    &日期和费用(10)
    &iif(len(canonicalizedAmzHeaders)GT 0,de(canonicalizedAmzHeaders&chr(10)),de(“”))
    &“/”&列表附加(bucket,objectKey,“/”;
    signingKey=createObject(“java”,“javax.crypto.spec.SecretKeySpec”).init(variables.awsSecret.getBytes(),algo);
    mac=createObject(“java”,“javax.crypto.mac”).getInstance(algo);
    mac.init(签名密钥);
    signature=toBase64(mac.doFinal(stringToSign.getBytes());
    返回签名;
    
    完全是从这里偷来的:

    :)

    (既然我已经写好了,不妨把这篇文章发出去

    我可以看到两个问题

  • 日期需要以特定的方式格式化
  • 您需要使用
    LF
    而不是文字“\n”
  • 下面的结果与ie
    bWq2s1WEIj+Ydj0vQ697zp+IXMU=
    中的结果相匹配。注意:我使用了,但更改了它使用
    getBytes(“UTF-8)

    代码:

        <cfset newLine = chr(10)>
        <cfset secretAccessKey = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY">
        <cfset stringToSign = "GET#newLine##newLine##newLine#Tue, 27 Mar 2007 19:36:42 +0000#newLine#/johnsmith/photos/puppy.jpg">
        <cfset signature = hmacSHA1(secretAccessKey, stringToSign)>
        <cfset finalSignature = URLEncodedFormat(binaryEncode(signature, "base64"))>
        <cfoutput>finalSignature = #finalSignature#</cfoutput>
    


    **编辑2:

        <cfset newLine = chr(10)>
        <cfset secretAccessKey = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY">
        <cfset stringToSign = "GET#newLine##newLine##newLine#Tue, 27 Mar 2007 19:36:42 +0000#newLine#/johnsmith/photos/puppy.jpg">
        <cfset signature = hmacSHA1(secretAccessKey, stringToSign)>
        <cfset finalSignature = URLEncodedFormat(binaryEncode(signature, "base64"))>
        <cfoutput>finalSignature = #finalSignature#</cfoutput>
    
    我很确定其余的例子都是错误的。搜索结果中包含了另一个示例密钥。如果您在CF代码中替换它,签名就是您所期望的:
    rucSbH0yNEcP9oM2XNlouVI3BH4%3D

        <cfset secretAccessKey = "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o">
        <cfset stringToSign = "GET#newLine##newLine##newLine#1175139620#newLine#/johnsmith/photos/puppy.jpg">
    
    
    
    我使用的代码是从同一个源中挑选出来的(在链接的帖子中提到),不起作用。你能用亚马逊的例子试试看它是否对你有效吗?对我来说不行。当使用REST时,日期的格式与你说的一样。当只使用GET时,AWS需要UTC时间戳。请参阅同一页的稍后部分。不过,我会尝试更改换行符,看看这是否有帮助。好的,让我看一下下面的例子。Chan将LF从CF获取哈希值以匹配PHP的哈希值,但它与amazon的哈希值不匹配。谢谢,已经很有用了。到目前为止,我已经更新了问题以反映您的答案,但仍然迫切需要一种方法让amazon识别我的请求。当您在文档错误上浪费时间时,您不讨厌吗?;-)
        <cfset secretAccessKey = "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o">
        <cfset stringToSign = "GET#newLine##newLine##newLine#1175139620#newLine#/johnsmith/photos/puppy.jpg">