I am trying to send a test request to the Swedish micro payment system Swish.
When running the code below, I get the error "SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')])"
My OpenSSl version is 1.1.1j which means it supports TLS 1.2 which Swish requires.
What do I need to change to make it work?
import json
from requests_pkcs12 import put
url = "https://mss.cpc.getswish.net/swish-cpcapi/api/v2/paymentrequests/F628384EC1744F9BB1F871EA67CB8BA5"
clientP12 = "Swish_Merchant_TestCertificate_1234679304.p12"
signingCert = "Swish_Merchant_TestSigningCertificate_1234679304.pem"
payload = {
"payeePaymentReference": "4",
"callbackUrl": "https://mysite/API/on_swish_payment_done/?payeePaymentReference=4",
"payerAlias": "0701234567",
"payeeAlias": "1234679304",
"amount": "100.00",
"currency": "SEK"
}
headers = {'content-type': 'application/json'}
r = put(url,
data=json.dumps(payload),
headers=headers,
pkcs12_filename=clientP12,
pkcs12_password='swish',
verify=signingCert
)
I think you should use the Swish_TLS_RootCA.pem as verify. Afaik the signing certificate is only used to sign the payload for Swish Payouts
Related
I'am making a script that can create and sign Certificate on Mikrotik using their REST API.
The script already worked in creating the Certificate, the problem is, signing it.
In Mikrotik Command Line, signing a certificate requires Unnamed Parameter, which i dont know how to specify it in the REST API Request.
Here is the detail about the Commands that translates to the REST API Request
Creating A Certificate (Worked)
CMD:
> /certificate add name=client-template-to-issue copy-from="client-template" common-name="$USERNAME#$CN"
REST:
URL: https://vpn.mydomain.com/rest/certificate/add
Body: {
"common-name": "$USERNAME#$CN",
"name":"client-template-to-issue",
"copy-from":"client-template"
}
Response: {
"ret": "*14"
}
Signing A Certificate (Diddnt Work)
CMD:
/certificate sign client-template-to-issue ca="$CN" name="$USERNAME#$CN"
REST:
URL: https://vpn.mydomain.com/rest/certificate/sign
Body: {
"ca": "$CN",
"name":"$USERNAME#$CN"
}
Response: {
"detail": "failure: At least one field specifying certificate name must be set!",
"error": 400,
"message": "Bad Request"
}
So how do i fix this? the command line suggest that there is a Unnamed Parameter to specify for it to work. i already tried with the URL like this
https://vpn.mydomain.com/rest/certificate/sign/*14
and it still doesnt work
The following worked for me:
URL: https://vpn.mydomain.com/rest/certificate/sign
Body: {
"ca": "$CN",
"number":"client-template-to-issue" # the "name" entry from your example of creating a certificate
}
I'm just not sure if this is a bug. Tested on ROS 7.7
I'm new to VISA developer and trying to send requests to https://sandbox.api.visa.com/cofds-web/v1/datainfo to check whether the credit card is valid or not in Python.
Python code:
cert = 'C:\\Users\\user\\visa_cert\\cert.pem'
ca_cert = 'C:\\Users\\user\\visa_cert\\ca_cert.cer'
key = 'C:\\Users\\user\\visa_cert\\my_key.pem'
user_id = 'your user id of your project'
password = 'your password of your project'
timeout = 10
cred_info = 'credit_info.json'
payload = json.loads('''{
"requestHeader": {
"requestMessageId": "6da6b8b024532a2e0eacb1af58581",
"messageDateTime": "2019-02-35 05:25:12.327"
},
"requestData": {
"pANs": [
4072208010000000
],
"group": "STANDARD"
}
}
''')
try:
response = requests.post(url,
verify = (ca_cert),
cert=(cert, key),
# headers = headers,
auth=(user_id, password),
json = payload,
timeout=timeout
)
except Exception as e:
print(e)
Execution itself succeeded, but the response says the "Ecpectd input credential was not present"
Response header and contetns are as below.
# response header:
{'Server': 'nginx', 'Date': 'Fri, 03 Jun 2022 13:52:17 GMT', 'Content-Type': 'application/json;charset=UTF-8', 'Content-Length': '130', 'Connection': 'keep-alive', 'X-SERVED-BY': 'c6795c5t4', 'X-CORRELATION-ID': '1654264337_872_241384137_c6795c5t4_VDP_WS', 'X-ERROR-ORIGIN': '9200', 'X-APP-STATUS': '400', 'X-Frame-Options':
'SAMEORIGIN', 'X-XSS-Protection': '0', 'X-Content-Type-Options': 'nosniff', 'Strict-Transport-Security': 'max-age=31536000;includeSubdomains', 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '-1'}
# response content:
b'{"responseStatus":{"status":400,"code":"9125","severity":"ERROR","message":"Expected input credential was not present","info":""}}'
I followed the instruction here(https://developer.visa.com/pages/working-with-visa-apis/two-way-ssl#configuring_a_twoway_ssl_keystor...) to generate the CA certificate, double-checked my user_id and password are correct and two-way SSL certificate is active.
I googled this error, but I'm still not sure how to fix this problem.
Thank you.
passiveradio
So this API requires Message Level Encryption so I have been struggling to figure out how to implement the MLE with the API, if you try to use the Visa Developer Center with MLE enabled you will get the error you're getting but if you run it with MLE enabled it works.
So if you figure out how to implement MLE in the code I would be grateful because the documentation is very vague.
https://developer.visa.com/pages/encryption_guide
I used the following API in postman with integration key, client secret from the Admin API application but no luck.
GET: https://api-123abc.duosecurity.com/auth/v2/check
Furthermore,
I used basic auth for authorization
Integration key for username and created the password via
https://www.freeformatter.com/hmac-generator.html#ad-output (used
integration key for string and client secret from the duo UI)
I used the following headers:
Authorization:Basic
Integration-key:Secret-key
Date:Fri, 20 May 2022 02:26:39 +0000
Content-Type:application/x-www-form-urlencoded
Besides this I used the code
btoa('integration key:secret key')
to generate authentication code but it still gives the following error
{
"code": 40301,
"message": "Access forbidden",
"message_detail": "Wrong integration type for this API.",
"stat": "FAIL"
}
Add Postman PreRequest script
update/replace integration and secret keys in below script
follow docs
const cannon = [
new Date().toUTCString(),
pm.request.method,
pm.request.url.host.join('.'),
'/'+pm.request.url.path.join('/'),
];
if (pm.request.body.urlencoded){
cannon.push(pm.request.body.urlencoded);
}
function hmacSign(cannon, integrationKey, secretKey){
const message = cannon.join("\n");
console.log(message);
var hmac = CryptoJS.HmacSHA1(message, secretKey)
return btoa(`${integrationKey}:${hmac}`)
}
const sign = hmacSign(cannon, "DIWJ8X6AEYOR5OMC6TQ1", "Zh5eGmUq9zpfQnyUIu5OL9iWoMMv5ZNmk3zLJ4Ep")
pm.request.headers.add({
key: "authorization",
value: sign
});
I got an old web app runing Meteor 1.6.1.1 in which we request data from restcountries.com. Unfortuanately Meteor now thinks that their certificate has expired. Presumable because of the R3 Certificate that expired a while ago. Since migration/update to another framework is not planned, I wanted to disable certificate verification for now. But I can't figure out how. I've tried setting strictSSL to false in the call options, but it doesn't have any effect:
var response = HTTP.get(apiUrl, {
headers: {
"User-Agent": "Meteor/1.0", //Required for EUROSTAT provider
"Accept": "application/json"
},
strictSSL: false
}).data;
You can use the env variable of Node: NODE_TLS_REJECT_UNAUTHORIZED
https://docs.meteor.com/expired-certificate.html
Goal
I want to authenticate my daemon application with a certificate instead of client secret against Microsoft Graph & want understand the exact request necessary to successfully authenticate.
Using the following resources:
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#second-case-access-token-request-with-a-certificate
https://learn.microsoft.com/en-us/graph/auth-v2-service
https://laurakokkarinen.com/authenticating-to-office-365-apis-with-a-certificate-step-by-step/
https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-OAPX/%5BMS-OAPX%5D.pdf
Could there be an error in the Azure AD configuration of your app?
All Azure AD configurations were tested prior with a client-secret.
The certificate public key was also uploaded beforehand:
Request & Problem
I managed to create this request (tenant-id, client-id, certificates are just dummies)
Values:
grant_type: urn:ietf:params:oauth:client-assertion-type:jwt-bearer
client_assertion_type: logon_cert
client_id: my-client-id-from-azure
scope: https://graph.microsoft.com/.default
client_assertion: JWT containing
Header: (x5t contains the base64 encoded certificate sha1 thumbprint from the uploaded certificate, see above picture)
{
"typ": "JWT",
"x5t": "QUY4RjBERERGMDBBOURGRUQ0MzkzODRGQTYzMjhFQ0FBRDNBOEUzNw",
"alg": "RS256"
}
Payload:
{
"iss": "my-client-id-from-azure",
"sub": "my-client-id-from-azure",
"scope": "https://graph.microsoft.com/.default",
"aud": "https://login.microsoftonline.com/my-tenant-id/oauth2/v2.0/token",
"iat": 1625591612,
"nbf": 1625591612,
"exp": 1625595212,
"jti": "some-dynamically-generated-uuid"
}
Request:
POST https://login.microsoftonline.com/my-tenant-id/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=eyJ0eXAiOiJKV1QiLCJ4NXQiOiJSRFUwTUVRd016RkdOakpGTUVOQk5UaEVPVFpGTXpBNFFrRkZNMFUzTmpFd01USkVPRFUwUWc9PSIsImFsZyI6IlJTMjU2In0.eyJpc3MiOiJteS1jbGllbnQtaWQtZnJvbS1henVyZSIsInNjb3BlIjoiaHR0cHM6Ly9ncmFwaC5taWNyb3NvZnQuY29tLy5kZWZhdWx0IiwiYXVkIjoiaHR0cHM6Ly9sb2dpbi5taWNyb3NvZnRvbmxpbmUuY29tL215LXRlbmFudC1pZC9vYXV0aDIvdjIuMC90b2tlbiIsImlhdCI6MTYyNTY2MDU3MywibmJmIjoxNjI1NjYwNTczLCJzdWIiOiJteS1jbGllbnQtaWQtZnJvbS1henVyZSIsImp0aSI6IjlhZTQwYTk2LTliMTgtNDRhOS1hOWM3LWE3NDZjMjA4OGUxMyIsImV4cCI6MTYyNTY2NDE3M30.pw81FeQirjIsnXGlLSLDG5Cz4rIdOuF54M8fPmDlubNs0-DoHpkj9OdrCXlCPDWvQLaYAs3mH9kcSP-Z4rf-NgaiCF-ECL-iA2xxvQ3n8JSDeaPPkLd6tMAKeMm5sEIcap7RJ8Fnt1kCflVAOIuYCh_zijJd9etQj-2wfbtiHnHtlpg6n0-4u7oj9wAx2naIU6J4dtgdIPypBTfwxyXtZWy0nkM8jde6Jr7CqVVlECdf7wyGwN1Jhwf6PeihKn8peQKaXzVnMmLpcCmjNENnTRM5PmhEQkCGOOR4hMJkdfCONWmOtSoRlndhCQypBQM-fzl_-sDviXNjAYKvrYTUM-kwZZBqKyzdekqMnxxwnaKmF1uGVnrSjad_AfW0A9Vg9UpaqGvsbe8Doq15I7KE46kzd4y3fDoibDQG-qaYL8LYKcrVUDkTw_PNfiyihlcaGjBvHVaMBsYhJJlNnohktO0OES0WO0iUlj_M0PuOF7JxYsPAQZM5uZGPTRCQhen_8khQ8z70C2YYz965kCROL9-WC53Ezbt1R0QjHR4UupV3CtQfZe_BkTG8vYu7SMWbxDEGZKb6cRsTCgzqmd6l3f6OGojQA_EAvFJpL0kw0d_tfYnY4ZkyLdcI3G3fMyhicm7qmkiq7ZRdnGL2uCl-tpxsoLD7UbvVPD3CS_LNAp4&client_id=my-client-id-from-azure&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&grant_type=client_credentials
Response:
I'm expecting an access token, instead, I get a 401 Unauthorized stating
{
"error": "invalid_client",
"error_description": "AADSTS700027: Client assertion contains an invalid signature. [Reason - The key was not found., Thumbprint of key used by client: 'some-other-thumbprint', Please visit the Azure Portal, Graph Explorer or directly use MS Graph to see configured keys for app Id 'my-app-id'. Review the documentation at https://learn.microsoft.com/en-us/graph/deployments to determine the corresponding service endpoint and https://learn.microsoft.com/en-us/graph/api/application-get?view=graph-rest-1.0&tabs=http to build a query request URL, such as 'https://graph.microsoft.com/beta/applications/my-app-id']\r\nTrace ID: some-uuid\r\nCorrelation ID: some-other-uuid\r\nTimestamp: 2021-07-07 12:25:46Z",
"error_codes": [
700027
],
"timestamp": "2021-07-06 12:25:46Z",
"trace_id": "some-uuid",
"correlation_id": "some-other-uuid",
"error_uri": "https://login.microsoftonline.com/error?code=700027"
}
I'm lost as to what the issue could be.
Question:
What am I doing wrong?
So the issue came from the way the x5t header was being created.
I misunderstood the docs that clearly state the fingerprint as being a hex before encoding it base64:
With a fingerprint like this 204C837E10143C1428D7911CB60ED0075C3E1062, the string needs to be treated as a HEX binary, not as a simple string.
Example (PHP):
Pseudo code:
// load certificate
certificate = load_file('/path/to/cert.pem')
// fingerprint is hex string 204C837E10143C1428D7911CB60ED0075C3E1062
certificate_fingerprint_hex_string = x509fingerprint($certificate)
// hexademical string is being converted to binary format
certificate_fingerprint_binary = hex_to_binary(certificate_fingerprint_hex_string)
// binary format gets base64 encoded (not base64url) to IEyDfhAUPBQo15Ectg7QB1w+EGI=
x5t = base64_encode(certificate_fingerprint_binary)
Request (Documentation)
Method and headers
POST https://login.microsoftonline.com/my-tenant-id/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Body (not yet formatted according to Content-Type)
client_id: my-client-id-from-azure
client_assertion_type: urn:ietf:params:oauth:client-assertion-type:jwt- bearer
client_assertion: see below a JWT click here for details
grant_type: client_credentials
scope: https://graph.microsoft.com/.default
client_assertion
Header: (x5t contains the base64 encoded certificate sha1 thumbprint from the uploaded certificate, see above picture)
{
"typ": "JWT",
"x5t": "IEyDfhAUPBQo15Ectg7QB1w+EGI=",
"alg": "RS256"
}
Payload:
{
"iss": "my-client-id-from-azure",
"sub": "my-client-id-from-azure",
"scope": "https://graph.microsoft.com/.default",
"aud": "https://login.microsoftonline.com/my-tenant-id/oauth2/v2.0/token",
"iat": 1625591612,
"nbf": 1625591612,
"exp": 1625595212,
"jti": "some-dynamically-generated-uuid"
}
Based on some search, here how I create the JWT token to request accessToken:
package required
composer required firebase/php-jwt ramsey/uuid guzzlehttp/guzzle
php code
<?php
use Firebase\JWT\JWT;
use Ramsey\Uuid\Uuid;
require_once (__DIR__.'/vendor/autoload.php');
$guzzle = new \GuzzleHttp\Client();
$authTenant = '';
$clientID = '';
$certPubFile = '';
$certPrivFile = '';
$url = 'https://login.microsoftonline.com/' . $authTenant . '/oauth2/v2.0/token';
$cert = openssl_x509_read(file_get_contents($certPubFile));
$sha1_hash = openssl_x509_fingerprint($cert); // sha1 hash (x5t parameter)
$jwt = JWT::encode([
'aud' => 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
'exp' => (new DateTime())->add(new DateInterval('PT150S'))->format('U'),
'nbf' => time() - 1,
'iss' => clientID,
'sub' => clientID,
'jti' => Uuid::uuid4(),
],
file_get_contents($certPrivFile),
'RS256',
null,
[
"alg" => "RS256",
"typ" => "JWT",
"x5t" => base64_encode(pack('H*', $sha1_hash)),
]
);
$authFormParameters = [
'client_id' => clientID,
'client_assertion_type' => 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
'client_assertion' => $jwt,
'scope' => 'https://graph.microsoft.com/.default',
'grant_type' => 'client_credentials',
];
$token = json_decode($guzzle->post($url, [
'form_params' => $authFormParameters,
])->getBody()->getContents());
$accessToken = $token->access_token;