ColdFusion oAuth RSA-SHA1 authorisation for Xero wrapper -


i'm writing wrapper xero api, using oauth , two-legged authentication. "private" application, xero calls it, requires rsa-sha1 signature. coldfusion oauth wrapper doesn't have function encrypting in rsa-sha1, hmac-sha1. on cf9.

consequently, in course of running request, following error:

signature_method_rejected private applications must use rsa-sha1 signature method 

so, looks call working, issue signature method. found thought looked solution created, follows:

<cffunction name="rsa_sha1" returntype="string" access="public" descrition="rsa-sha1 computation based on supplied private key , 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 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 line below --->                <cfset sig.initsign(keyfactory.getinstance("rsa").generateprivate(keyspec.init(keybytes)))>                 <cfset sig.update(jmsg)>                <cfset signbytes = sig.sign()>                 <cfreturn tobase64(signbytes)>          </cffunction> 

it receives following arguments:

sformat     utf-8 signkey     0jxxxxxxxxxxxxxxxxxxxp& signmessage     get&https%3a%2f%2fapi.xero.com%2fapi.xro%2f2.0%2fcontacts&contactid%3d%26contactnumber%3d%26name%3d7-eleven%26oauth_consumer_key%3dxxxxxxxxxxxxxxxx%26oauth_nonce%3dxxxxxxxxxxxxxxxx%26oauth_signature_method%3drsa-sha1%26oauth_timestamp%3d1339055484%26oauth_version%3d1.0  

however, produces following error:

could not read ber data.(asn1lengths.determinelengthlen: length greater 0x7fff,ffff.)  coldfusion cannot determine line of template caused error. caused error in exception handling subsystem.  

can shed light on this?

edit ----

enter image description here

there link uploading public cert, did. there note saying: "note, private applications, consumer token , secret used access token , secret.". assuming need "consumer secret" value shown there in order sign request. being case, how convert secret key value rsa-sh1 format signature?

(summary comments)

according their api private applications must generate rsa public/private pair (one time event). upload public certificate server, , use private key sign requests using rsa-sha1. if followed instructions in link private key in pem format, key value encoded in base64, enclosed within begin/end wrapper:

    -----begin rsa private key-----     xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx     xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx     ....     -----end rsa private key----- 

you need extract portion between wrapper before using key pkcs8encodedkeyspec. there @ least 3 ways that. simplest option use string functions:

    // read in  key file , remove 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" ); 

another option use bouncycastle pemreader class. (and supports password protected keys).

    pathtokey  = "c:/path/to/file/privatekey.pem";     provider   = createobject("java", "org.bouncycastle.jce.provider.bouncycastleprovider").init();     security   = createobject("java", "java.security.security").addprovider( provider );     filereader = createobject("java", "java.io.filereader").init( pathtokey );     keyreader  = createobject("java", "org.bouncycastle.openssl.pemreader").init( filereader);     privatekey = keyreader.readobject().getprivate();     rawkey     = binaryencode( privatekey.getencoded(), "base64" );     yourmessage = "get&https%3a%2f%2fapi.xero.com%2fapi.xro%2f2.0%2fcontacts&....";     signature  = rsa_sha1( rawkey, yourmessage, "utf-8" ); 

yet option convert key der format openssl

    $ openssl pkcs8 -topk8 -in privatekey.pem -outform der -nocrypt -out privatekey.pk8      pathtokey = "c:/path/to/file/privatekey.pk8";     bytes = binaryencode( filereadbinary(pathtokey), "base64");     yourmessage = "get&https%3a%2f%2fapi.xero.com%2fapi.xro%2f2.0%2f...";     signature = rsa_sha1(rawkey, testmessage, "utf-8"); 

note if posted actual private key here (or on forum), compromised. recommend generating new keys.


Comments

Popular posts from this blog

How do you change vbulletin's home page to the forums instead of the default (CMS or Activity Stream)? -

c++ - Troubles when compiling phash program -