Chilkat HOME .NET Core C# Android™ AutoIt C C# C++ Chilkat2-Python CkPython Classic ASP DataFlex Delphi ActiveX Delphi DLL Go Java Lianja Mono C# Node.js Objective-C PHP ActiveX PHP Extension Perl PowerBuilder PowerShell PureBasic Ruby SQL Server Swift 2 Swift 3,4,5... Tcl Unicode C Unicode C++ VB.NET VBScript Visual Basic 6.0 Visual FoxPro Xojo Plugin
(PureBasic) ebay: Add Digital Signature to HTTP RequestSee more eBay ExamplesDemonstrates how to add a digital signature to an ebay HTTP request. For more information, see https://developer.ebay.com/develop/guides/digital-signatures-for-apis
IncludeFile "CkBinData.pb" IncludeFile "CkDateTime.pb" IncludeFile "CkPrivateKey.pb" IncludeFile "CkHttp.pb" IncludeFile "CkEdDSA.pb" IncludeFile "CkStringBuilder.pb" IncludeFile "CkHttpResponse.pb" Procedure ChilkatExample() ; This example requires the Chilkat API to have been previously unlocked. ; See Global Unlock Sample for sample code. success.i ; Note: Ebay provides a Key Management API ; See https://developer.ebay.com/api-docs/developer/key-management/overview.html ; The following test keys can be used: ; ; Ed25519 ; ; Private Key: ; ; -----BEGIN PRIVATE KEY----- ; MC4CAQAwBQYDK2VwBCIEIJ+DYvh6SEqVTm50DFtMDoQikTmiCqirVv9mWG9qfSnF ; -----END PRIVATE KEY----- strPrivateKey.s = "MC4CAQAwBQYDK2VwBCIEIJ+DYvh6SEqVTm50DFtMDoQikTmiCqirVv9mWG9qfSnF" ; ; Public Key: ; ; -----BEGIN PUBLIC KEY----- ; MCowBQYDK2VwAyEAJrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs= ; -----END PUBLIC KEY----- strPublicKey.s = "MCowBQYDK2VwAyEAJrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs=" ; This example assumes you got a JWE for your given private key from the Ebay Key Management REST API. ; This JWE is just for example: strJwe.s = "eyJ6aXAiOiJERUYiLCJlbmMiOiJBMjU2R0NNIiwidGFnIjoiSXh2dVRMb0FLS0hlS0Zoa3BxQ05CUSIsImFsZyI6IkEyNTZHQ01LVyIsIml2IjoiaFd3YjNoczk2QzEyOTNucCJ9.2o02pR9SoTF4g_5qRXZm6tF4H52TarilIAKxoVUqjd8.3qaF0KJN-rFHHm_P.AMUAe9PPduew09mANIZ-O_68CCuv6EIx096rm9WyLZnYz5N1WFDQ3jP0RBkbaOtQZHImMSPXIHVaB96RWshLuJsUgCKmTAwkPVCZv3zhLxZVxMXtPUuJ-ppVmPIv0NzznWCOU5Kvb9Xux7ZtnlvLXgwOFEix-BaWNomUAazbsrUCbrp514GIea3butbyxXLNi6R9TJUNh8V2uan-optT1MMyS7eMQnVGL5rYBULk.9K5ucUqAu0DqkkhgubsHHw" sbBody.i = CkStringBuilder::ckCreate() If sbBody.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkStringBuilder::ckAppend(sbBody,"{" + Chr(34) + "hello" + Chr(34) + ": " + Chr(34) + "world" + Chr(34) + "}") Debug "Body of request:" Debug CkStringBuilder::ckGetAsString(sbBody) ; ------------------------------------------------- ; Build the signature base string... sbSigBase.i = CkStringBuilder::ckCreate() If sbSigBase.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkStringBuilder::ckAppend(sbSigBase,Chr(34) + "content-digest" + Chr(34) + ": sha-256=:") CkStringBuilder::ckAppend(sbSigBase,CkStringBuilder::ckGetHash(sbBody,"sha256","base64","utf-8")) CkStringBuilder::ckAppend(sbSigBase,":" + Chr(10)) CkStringBuilder::ckAppend(sbSigBase,Chr(34) + "x-ebay-signature-key" + Chr(34) + ": ") CkStringBuilder::ckAppend(sbSigBase,strJwe) CkStringBuilder::ckAppend(sbSigBase,Chr(10)) CkStringBuilder::ckAppend(sbSigBase,Chr(34) + "@method" + Chr(34) + ": POST" + Chr(10)) ; This is the path part of the URL without query params... CkStringBuilder::ckAppend(sbSigBase,Chr(34) + "@path" + Chr(34) + ": ") CkStringBuilder::ckAppend(sbSigBase,"/verifysignature") CkStringBuilder::ckAppend(sbSigBase,Chr(10)) ; The is the domain, such as "api.ebay.com" w/ port if the port is something unusual. ; In this example, we're testing against a local docker test server (see the info at https://developer.ebay.com/develop/guides/digital-signatures-for-apis) ; Normally, I think it would just be "api.ebay.com" instead of "localhost:8080". CkStringBuilder::ckAppend(sbSigBase,Chr(34) + "@authority" + Chr(34) + ": ") CkStringBuilder::ckAppend(sbSigBase,"localhost:8080") CkStringBuilder::ckAppend(sbSigBase,Chr(10)) CkStringBuilder::ckAppend(sbSigBase,Chr(34) + "@signature-params" + Chr(34) + ": ") sbSigInput.i = CkStringBuilder::ckCreate() If sbSigInput.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkStringBuilder::ckAppend(sbSigInput,"(" + Chr(34) + "content-digest" + Chr(34) + " " + Chr(34) + "x-ebay-signature-key" + Chr(34) + " " + Chr(34) + "@method" + Chr(34) + " " + Chr(34) + "@path" + Chr(34) + " " + Chr(34) + "@authority" + Chr(34) + ")") CkStringBuilder::ckAppend(sbSigInput,";created=") dt.i = CkDateTime::ckCreate() If dt.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkDateTime::ckSetFromCurrentSystemTime(dt) unixTimeNow.s = CkDateTime::ckGetAsUnixTimeStr(dt,0) CkStringBuilder::ckAppend(sbSigInput,unixTimeNow) CkStringBuilder::ckAppendSb(sbSigBase,sbSigInput) ; ------------------------------------------------- ; Sign the signature base string using the Ed25519 private key bdPrivKey.i = CkBinData::ckCreate() If bdPrivKey.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkBinData::ckAppendEncoded(bdPrivKey,strPrivateKey,"base64") privKey.i = CkPrivateKey::ckCreate() If privKey.i = 0 Debug "Failed to create object." ProcedureReturn EndIf success = CkPrivateKey::ckLoadAnyFormat(privKey,bdPrivKey,"") If success = 0 Debug CkPrivateKey::ckLastErrorText(privKey) CkStringBuilder::ckDispose(sbBody) CkStringBuilder::ckDispose(sbSigBase) CkStringBuilder::ckDispose(sbSigInput) CkDateTime::ckDispose(dt) CkBinData::ckDispose(bdPrivKey) CkPrivateKey::ckDispose(privKey) ProcedureReturn EndIf bdToBeSigned.i = CkBinData::ckCreate() If bdToBeSigned.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkBinData::ckAppendSb(bdToBeSigned,sbSigBase,"utf-8") eddsa.i = CkEdDSA::ckCreate() If eddsa.i = 0 Debug "Failed to create object." ProcedureReturn EndIf sigBase64.s = CkEdDSA::ckSignBdENC(eddsa,bdToBeSigned,"base64",privKey) If CkEdDSA::ckLastMethodSuccess(eddsa) = 0 Debug CkEdDSA::ckLastErrorText(eddsa) CkStringBuilder::ckDispose(sbBody) CkStringBuilder::ckDispose(sbSigBase) CkStringBuilder::ckDispose(sbSigInput) CkDateTime::ckDispose(dt) CkBinData::ckDispose(bdPrivKey) CkPrivateKey::ckDispose(privKey) CkBinData::ckDispose(bdToBeSigned) CkEdDSA::ckDispose(eddsa) ProcedureReturn EndIf Debug "sigBase64:" Debug sigBase64 ; ---------------------------------------------------------- ; Send the JSON POST http.i = CkHttp::ckCreate() If http.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkHttp::ckSetRequestHeader(http,"x-ebay-signature-key",strJwe) sbContentDigestHdr.i = CkStringBuilder::ckCreate() If sbContentDigestHdr.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkStringBuilder::ckAppend(sbContentDigestHdr,"sha-256=:") CkStringBuilder::ckAppend(sbContentDigestHdr,CkStringBuilder::ckGetHash(sbBody,"sha256","base64","utf-8")) CkStringBuilder::ckAppend(sbContentDigestHdr,":") CkHttp::ckSetRequestHeader(http,"Content-Digest",CkStringBuilder::ckGetAsString(sbContentDigestHdr)) sbSigHdr.i = CkStringBuilder::ckCreate() If sbSigHdr.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkStringBuilder::ckAppend(sbSigHdr,"sig1=:") CkStringBuilder::ckAppend(sbSigHdr,sigBase64) CkStringBuilder::ckAppend(sbSigHdr,":") CkHttp::ckSetRequestHeader(http,"Signature",CkStringBuilder::ckGetAsString(sbSigHdr)) CkStringBuilder::ckPrepend(sbSigInput,"sig1=") CkHttp::ckSetRequestHeader(http,"Signature-Input",CkStringBuilder::ckGetAsString(sbSigInput)) ; Add this header to make eBay actually check the signature. CkHttp::ckSetRequestHeader(http,"x-ebay-enforce-signature","true") ; Set the OAuth2 access token to add the "Authorization: Bearer <access_token>" to the header. CkHttp::setCkAuthToken(http, "your_oauth2_access_token") ; The signature base string constructed above is valid if we send this POST to "http://localhost:8080/verifysignature" ; Normally, you'll send your POST to some api.ebay.com endpoint. url.s = "http://localhost:8080/verifysignature" resp.i = CkHttp::ckPostJson2(http,"http://localhost:8080/verifysignature","application/json",CkStringBuilder::ckGetAsString(sbBody)) If CkHttp::ckLastMethodSuccess(http) = 0 Debug CkHttp::ckLastErrorText(http) CkStringBuilder::ckDispose(sbBody) CkStringBuilder::ckDispose(sbSigBase) CkStringBuilder::ckDispose(sbSigInput) CkDateTime::ckDispose(dt) CkBinData::ckDispose(bdPrivKey) CkPrivateKey::ckDispose(privKey) CkBinData::ckDispose(bdToBeSigned) CkEdDSA::ckDispose(eddsa) CkHttp::ckDispose(http) CkStringBuilder::ckDispose(sbContentDigestHdr) CkStringBuilder::ckDispose(sbSigHdr) ProcedureReturn EndIf Debug "Response status code: " + Str(CkHttpResponse::ckStatusCode(resp)) Debug "Response body:" Debug CkHttpResponse::ckBodyStr(resp) CkHttpResponse::ckDispose(resp) CkStringBuilder::ckDispose(sbBody) CkStringBuilder::ckDispose(sbSigBase) CkStringBuilder::ckDispose(sbSigInput) CkDateTime::ckDispose(dt) CkBinData::ckDispose(bdPrivKey) CkPrivateKey::ckDispose(privKey) CkBinData::ckDispose(bdToBeSigned) CkEdDSA::ckDispose(eddsa) CkHttp::ckDispose(http) CkStringBuilder::ckDispose(sbContentDigestHdr) CkStringBuilder::ckDispose(sbSigHdr) ProcedureReturn EndProcedure |
© 2000-2024 Chilkat Software, Inc. All Rights Reserved.