Xero包装的ColdFusion oAuth RSA-SHA1授权

Xero包装的ColdFusion oAuth RSA-SHA1授权,coldfusion,oauth,rsa,Coldfusion,Oauth,Rsa,我正在使用oAuth和双腿身份验证为XeroAPI编写一个包装器。正如Xero所说,它是一个“私有”应用程序,需要RSA-SHA1签名。Coldfusion oAuth包装器在RSA-SHA1中没有加密功能,只有HMAC-SHA1。我们在CF9上 因此,在运行GET请求的过程中,出现以下错误: signature_method_rejected Private applications must use the RSA-SHA1 signature method Could not read

我正在使用oAuth和双腿身份验证为XeroAPI编写一个包装器。正如Xero所说,它是一个“私有”应用程序,需要RSA-SHA1签名。Coldfusion oAuth包装器在RSA-SHA1中没有加密功能,只有HMAC-SHA1。我们在CF9上

因此,在运行GET请求的过程中,出现以下错误:

signature_method_rejected
Private applications must use the RSA-SHA1 signature method
Could not read BER data.(ASN1Lengths.determineLengthLen: length greater than 0x7FFF,FFFF.)

ColdFusion cannot determine the line of the template that caused this error. This is often caused by an error in the exception handling subsystem. 
因此,看起来GET调用正在工作,但问题在于签名方法。我发现了我认为类似于某人创建的解决方案,如下所示:

<cffunction name="rsa_sha1" returntype="string" access="public" descrition="RSA-SHA1 computation based on supplied private key and supplied base signature string.">
               <cfargument name="signKey" type="string" required="true" hint="base64 formatted PKCS8 private key">
               <cfargument name="signMessage" type="string" required="true" hint="msg to sign">
               <cfargument name="sFormat" type="string" required="false" default="UTF-8">

               <cfset var jKey = JavaCast("string", arguments.signKey)>
               <cfset var jMsg = JavaCast("string",arguments.signMessage).getBytes(arguments.sFormat)>

               <cfset var key = createObject("java", "java.security.PrivateKey")>
               <cfset var keySpec = createObject("java","java.security.spec.PKCS8EncodedKeySpec")>
               <cfset var keyFactory = createObject("java","java.security.KeyFactory")>
               <cfset var b64dec = createObject("java", "sun.misc.BASE64Decoder")>

               <cfset var sig = createObject("java", "java.security.Signature")>

               <cfset var byteClass = createObject("java", "java.lang.Class")>
               <cfset var byteArray = createObject("java","java.lang.reflect.Array")>

               <cfset byteClass = byteClass.forName(JavaCast("string","java.lang.Byte"))>
               <cfset keyBytes = byteArray.newInstance(byteClass, JavaCast("int","1024"))>
               <cfset keyBytes = b64dec.decodeBuffer(jKey)>
               <!--- keyBytes = 48-111-10345-125-5349-114-581835-28-330-3984120-2848-4384-1-43 --->

               <cfset sig = sig.getInstance("SHA1withRSA", "SunJSSE")>
<!--- error occurs on the line below --->
               <cfset sig.initSign(keyFactory.getInstance("RSA").generatePrivate(keySpec.init(keyBytes)))> 
               <cfset sig.update(jMsg)>
               <cfset signBytes = sig.sign()>

               <cfreturn ToBase64(signBytes)>
         </cffunction>
但是,这会产生以下错误:

signature_method_rejected
Private applications must use the RSA-SHA1 signature method
Could not read BER data.(ASN1Lengths.determineLengthLen: length greater than 0x7FFF,FFFF.)

ColdFusion cannot determine the line of the template that caused this error. This is often caused by an error in the exception handling subsystem. 
有人能解释一下吗

编辑 ----

有一个用于上传公共证书的链接,我做到了。还有一个注释说:“注意,对于私有应用程序,消费者令牌和密码也用作访问令牌和密码。”。所以我假设我需要这里显示的“consumersecret”值来签署请求。在这种情况下,如何将该密钥值转换为RSA-SH1格式进行签名?

(评论摘要)

根据私有应用程序,必须生成RSA公共/私有对(一次性事件)。然后将公共证书上载到其服务器,并使用私钥使用RSA-SHA1对所有请求进行签名。如果您按照链接中的说明进行操作,您的私钥将采用
PEM
格式,即base64中编码的键值,包含在开始/结束包装中:

    -----BEGIN RSA PRIVATE KEY-----
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    ....
    -----END RSA PRIVATE KEY-----
在使用带有
PKCS8EncodedKeySpec
的密钥之前,需要提取包装器之间的部分。至少有三种方法可以做到这一点。最简单的选择是使用字符串函数:

    // read in the  key file and remove the wrapper
    pathToKey = "c:/path/to/file/privateKey.pem";
    rawKey = FileRead( pathToKey );
    rawKey = replace( rawKey, "-----BEGIN RSA PRIVATE KEY-----"& chr(10), "" );
    rawKey = replace( rawKey, "-----END RSA PRIVATE KEY-----", "" );

    yourMessage = "GET&https%3A%2F%2Fapi.xero.com%2Fapi.xro%2F2.0%2F...";
    signature = rsa_sha1( rawKey, yourMessage, "utf-8" );
另一个选项是使用BouncyCastle类。它可以为您完成这一切(还支持受密码保护的密钥)

另一个选择是

注意如果您在此处(或其他论坛)发布了您的实际私钥,则该私钥已被泄露。因此,我强烈建议生成新密钥。

(评论摘要)

根据私有应用程序,必须生成RSA公共/私有对(一次性事件)。然后将公共证书上载到其服务器,并使用私钥使用RSA-SHA1对所有请求进行签名。如果您按照链接中的说明进行操作,您的私钥将采用
PEM
格式,即base64中编码的键值,包含在开始/结束包装中:

    -----BEGIN RSA PRIVATE KEY-----
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    ....
    -----END RSA PRIVATE KEY-----
在使用带有
PKCS8EncodedKeySpec
的密钥之前,需要提取包装器之间的部分。至少有三种方法可以做到这一点。最简单的选择是使用字符串函数:

    // read in the  key file and remove the wrapper
    pathToKey = "c:/path/to/file/privateKey.pem";
    rawKey = FileRead( pathToKey );
    rawKey = replace( rawKey, "-----BEGIN RSA PRIVATE KEY-----"& chr(10), "" );
    rawKey = replace( rawKey, "-----END RSA PRIVATE KEY-----", "" );

    yourMessage = "GET&https%3A%2F%2Fapi.xero.com%2Fapi.xro%2F2.0%2F...";
    signature = rsa_sha1( rawKey, yourMessage, "utf-8" );
另一个选项是使用BouncyCastle类。它可以为您完成这一切(还支持受密码保护的密钥)

另一个选择是


注意如果您在此处(或其他论坛)发布了您的实际私钥,则该私钥已被泄露。因此,我强烈建议您生成新密钥。

您是如何生成密钥的?我们正在使用oauth库。注意,在我的示例中,我用“x”屏蔽了大部分密钥,我认为您需要生成自己的
RSA
私钥。然后将“base64格式的PKCS8私钥”字符串输入上述函数。描述一种方法和另一种方法的方法是。换句话说,上面的函数不适用于HMAC-SHA1值。您需要一个
RSA
私钥,以特定的方式编码。如果你已经有了,我相信代码是相对简单的。不,根据私人应用程序,不使用密钥进行签名。您必须生成一个
RSA
public/private对(一次性事件)。然后将您的公共证书上载到他们的服务器。他们将使用它来验证您的请求是否由您而不是其他人签署。然后使用您的私钥,使用RSA-SHA1对所有请求进行签名。您是如何生成密钥的?我们使用的是oauth库。注意,在我的示例中,我用“x”屏蔽了大部分密钥,我认为您需要生成自己的
RSA
私钥。然后将“base64格式的PKCS8私钥”字符串输入上述函数。描述一种方法和另一种方法的方法是。换句话说,上面的函数不适用于HMAC-SHA1值。您需要一个
RSA
私钥,以特定的方式编码。如果你已经有了,我相信代码是相对简单的。不,根据私人应用程序,不使用密钥进行签名。您必须生成一个
RSA
public/private对(一次性事件)。然后将您的公共证书上载到他们的服务器。他们将使用它来验证您的请求是否由您而不是其他人签署。然后使用您的私钥使用RSA-SHA1对所有请求进行签名。是的,最后得到了一个返回数据的GET操作。非常感谢。是的,终于得到了一个返回数据的GET操作。非常感谢。