Шифрование номера карты CyberSource (RSA-OAEP-256) - PullRequest
0 голосов
/ 08 марта 2020

Кто-нибудь знает здесь, как мне зашифровать номер карты в кибер-источнике?

Я пытался зашифровать мой с помощью онлайн-инструмента шифрования RSAOAEP, но я получил этот ответ

{
    "responseStatus": {
        "status": 400,
        "reason": "DECRYPTION_ERROR",
        "message": "Cannot decrypt PAN (RsaOaep256): data hash wrong",
        "correlationId": null,
        "details": [],
        "_embedded": {}
    },
    "_links": {
        "self": null,
        "documentation": [],
        "next": []
    }
}

там документация кажется не достаточно для новичка ie как я

1 Ответ

0 голосов
/ 24 марта 2020

Мне удалось заставить работать Flex API. Но какой SDK вы используете? Я реализовал это с React Native v0.61.5 с Typescript и несколькими криптографическими c библиотеками: реагировать-нативно-крипто , isomorphi c -webcrypto , crypto- js, js -base64 и буфер . Но в основном это можно сделать на любом Javascript фреймворке.

Я полагаю, у вас есть /Keys запрос, работающий, и я думаю, вы указали от encryptionType до RsaOaep256.

Далее шаг - импортировать JSON веб-ключ (JWK), полученный вами от предыдущего шага, и зашифровать номер карты с помощью импортированного ключа.

Импортировать JWK

import webcrypto from "isomorphic-webcrypto"

const importKey = async (jsonWebKey: any) => {
  return webcrypto.subtle.importKey(
    "jwk",
    {
      ...jsonWebKey,
      alg: "RSA-OAEP-256",
      ext: true,
    },
    {
      name: "RSA-OAEP",
      hash: "SHA-256",
    },
    false,
    ["encrypt"],
  )
}

Шифрование номера карты

import { Buffer } from "buffer"
import webcrypto from "isomorphic-webcrypto"
import { Base64 } from "js-base64"

const encryptCardNumber = async (cardNumber: string, jsonWebKey: any): Promise<T> = {
  const cardNumberBuffer = Buffer.from(cardNumber)

  const publicKey = await importKey(jsonWebKey, "encrypt")

  const encryptedCardNumberBuffer = await webcrypto.subtle.encrypt(
    {
      name: "RSA-OAEP",
      hash: "SHA-256",
    },
    publicKey,
    cardNumberBuffer
  )

  return Base64.btoa(String.fromCharCode.apply(null, new Uint8Array(encryptedCardNumberBuffer)))
}

Результат этой функции может быть непосредственно передан как cardNumber в теле запроса в cardInfo.

После этого вы получите token, signature , signedFields и некоторые другие поля. Вы должны сверять полученные значения с подписью, чтобы убедиться, что значения не были подделаны.

Проверка подписи

Это довольно просто, нам просто нужен ключ publi c из /Keys запроса, который мы можем найти в der/publicKey.

import crypto from "react-native-crypto"

const verifySignature = (publicKey: string, signature: string, signedFields: string, data: any): booelan => {
  const dataToVerify = data.signedFields.split(",").map(field => data[field]).join(",")
  const verificationKey = `-----BEGIN PUBLIC KEY-----\n${publicKey}\n-----END PUBLIC KEY-----`

  return crypto.createVerify("RSA-SHA512").update(dataToVerify).verify(verificationKey, signature, "base64")
},

Я надеюсь, что это поможет вам или другим людям, имеющим проблемы с реализацией Flex API CyberSource, потому что это сказалось на мне ...

...