• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
3* Licensed under the Apache License, Version 2.0 (the "License");
4* you may not use this file except in compliance with the License.
5* You may obtain a copy of the License at
6*
7*     http://www.apache.org/licenses/LICENSE-2.0
8*
9* Unless required by applicable law or agreed to in writing, software
10* distributed under the License is distributed on an "AS IS" BASIS,
11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12* See the License for the specific language governing permissions and
13* limitations under the License.
14*/
15
16import CreateOrGet from './SingleInstanceHelper';
17import cryptoFramework from '@ohos.security.cryptoFramework';
18import util from '@ohos.util';
19
20export enum PayResult {
21  SUCCESS = 200,
22  FAIL = 400,
23  ERROR = 600,
24}
25
26export interface User {
27  name: string,
28  payPassword: string,
29}
30
31const TAG = 'PayServer';
32const TEXT_DECODER = util.TextDecoder.create('utf-8', { ignoreBOM: true });
33const TEXT_ENCODER = new util.TextEncoder();
34const SIGNER_INPUT = { data: TEXT_ENCODER.encodeInto('This is a test') };
35const BASE64 = new util.Base64Helper();
36// 支付服务端私钥
37const PAY_PRI_KEY = 'MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAMMWX1SJUPCshS1NIVVpqkaAfu/baUGqebuSo6NR00JokT54FWEJVPYrcrKQ+4TjGC0p6PavL7YeZ7kxBplnHunE2RcTo/r3LebZVunUqcWCxe1ZiV0YD++uZtegOEpTgd2w8Lib72+wQt68WO43I40wwySUX+X7dF1nSDNGA6YnAgMBAAECgYACZjYJ7h5mt1hz9CzixgfoEhB9lq82tYgFvInyqkD04iBXKlbo+Jpo5KPmek39lmVnuMo6rnDhxoH0DxxLqq8An4Hk6f/G1Eyc681sEicuas4zanpGWtPA3Y+an9ZwwTolVIkiJw6nM4hz8QdEeiFK34Bfl28dz9kg89ZrVomlwQJBAOEJPtA7QPwSuxix2E+BsPVNg/EqXgs+9HoyF+lrH8to5gTAZSjydT03d6FUZOZBsgPB/hL+Avh5YTUjhBV6khcCQQDd7jPFabvcyr5cKyS2TqYGmqTnhDX3LxgB35GE6jLlMO3teIY1HUsQsV2946lE4s7aqcalXa37Dw7yLxwlbGZxAkAggA5TUotzHF1rFpxP90IQW26X0O+eHix+zWdIrdD8tpypyQOTI1ktSyp64U5lNs233zeLlKXnLtiMLSHxXC9nAkAPbZvTwYH5225YYfdvZRBNrTqBjcNip7d3id9H6jAXlsszkwlhb+PkCTCHHuiJjWrr8JmKrXSG24kidPvz7hFBAkABQhnS1b3O4IIs5rdQTwcgBpzUk76csUQFB35g0IMV4jeHE7+84rNJDQ8hgStmyQvrLH8bBjX3xftxvj+q57cd';
38// 商户服务端公钥
39const MERCHANT_PUB_KEY = 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE/4Xcag3k5SBGX52KduDPcYBSEanwpo85kzGceENvQkhG0UinwwxSttkXv9os1pikfChaD5vR2BhXsco54SC/rA==';
40// 支付客户端私钥
41const PAY_CLIENT_PRI_KEY = 'MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAPvx0A4ex864EDiA8wDwY7/kqVDjzvsoC9pOSkkgMCRoBuWEADHiYoZrgrg9NLtPHONd0SD8Jk4B2eqym4ylB/bk87Jy4bbIdajeM86tvuS2R/RqPlOdFbeRoGFnlPITozGdQImH4eRfwRCnpYZqooIHDkPUWD2gDSuBmKCLqcP/AgMBAAECgYEAlrVgsoGhHjwmn9YrBp3F3Y0H53ZOYxjidjUs5K9XfP+pWHPstepo62W2bUVXnNBHRI7jQWrz8ufSlj0/JRO3Pb6CJp4u3Qw4ty/GAXtNUaaEb8Ll0SFkwu7TiUkHCEjnjF/aCkFVOAxwa2RT0GWs1uj+uqF7KyMylL4RZCyAnCkCQQD+74SDaTomcNHzPpVXyumZpmIxWpkP6GbcA0yjV3aw+K7IIHs20cYiNRXWw51Uh1aHTwqd8+/Ywq6IP9VHZT27AkEA/P8ZIoUZ/QsvIu0eUZRE9JaB4bcfD8RUGetqZhZA6J6Nd6uJ1nut/XG0JGa4wqSqBWGs8BBV6aDNuJzrzOYMjQJBAMMMwphAhEsw+pFfCqhXCY+Ta4FTTdSL/VbL93Dp1FfmjON1ZpA0w6EceI8Or2si+SMhaIAdSR7RJPP90tKDNU0CQExxX8zYXsPgjzuEXfbUUAl/OHtU82O2NJsoUJvL+YzP63rPL/TIpgfARWgCSa02R9EcdD6NEQhoeABiGbVthTkCQF8gsjNa6KIpfqEf4+DZFNO2o28ELyniY4O6xUKHWfiU7vKxRQ2DFYQ8Hv9Q07HB69kXc0p/XLJxjpX0K/Wpn2k=';
42const TEST_USER: User = {
43  name: 'test',
44  payPassword: '123456',
45};
46const HEXADECIMAL = 36;
47const CONTAINS_LETTERS = 2;
48const MIN_LENGTH = 2;
49const INDEX_ZERO = 0;
50
51class PayServer {
52  private orderString: string;
53  private merchantKey: cryptoFramework.KeyPair;
54  private payKey: cryptoFramework.KeyPair;
55  private payClientKey: cryptoFramework.KeyPair;
56
57  public async generatePayOrder(body: string): Promise<string> {
58    if (!this.payKey) {
59      let rsaGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024|PRIMES_2');
60      this.payKey = await rsaGenerator.convertKey(null, { data: BASE64.decodeSync(PAY_PRI_KEY) });
61    }
62    let decoder = cryptoFramework.createCipher('RSA1024|PKCS1');
63    await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, this.payKey.priKey, null);
64    let data = await decoder.doFinal({ data: BASE64.decodeSync(body) });
65    let bodyStr = TEXT_DECODER.decodeWithStream(data.data);
66    this.orderString = bodyStr + '&orderId=' + Array.from({
67      length: 17
68    }, () => Math.random().toString(HEXADECIMAL)[CONTAINS_LETTERS]).join('').toUpperCase();
69    return this.orderString;
70  }
71
72  public async pay(orderString: string, userName: string, password: string): Promise<PayResult> {
73    let temArr = orderString.split('&signer=');
74    if (temArr.length < MIN_LENGTH || temArr[INDEX_ZERO] !== this.orderString) {
75      return PayResult.ERROR;
76    }
77    if (!this.merchantKey) {
78      let eccGenerator = cryptoFramework.createAsyKeyGenerator('ECC256');
79      this.merchantKey = await eccGenerator.convertKey({ data: BASE64.decodeSync(MERCHANT_PUB_KEY) }, null);
80    }
81    let verifyer = cryptoFramework.createVerify('ECC256|SHA256');
82    await verifyer.init(this.merchantKey.pubKey);
83    let verifyOk = await verifyer.verify(SIGNER_INPUT, { data: BASE64.decodeSync(temArr[1]) });
84    if (!verifyOk) {
85      return PayResult.ERROR;
86    }
87    if (!this.payClientKey) {
88      let rsaGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024|PRIMES_2');
89      this.payClientKey = await rsaGenerator.convertKey(null, { data: BASE64.decodeSync(PAY_CLIENT_PRI_KEY) });
90    }
91    let decoder = cryptoFramework.createCipher('RSA1024|PKCS1');
92    await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, this.payClientKey.priKey, null);
93    let userNameData = await decoder.doFinal({ data: BASE64.decodeSync(userName) });
94    if (TEST_USER.name !== TEXT_DECODER.decodeWithStream(userNameData.data)) {
95      return PayResult.FAIL;
96    }
97    let passwordData = await decoder.doFinal({ data: BASE64.decodeSync(password) });
98    if (TEST_USER.payPassword !== TEXT_DECODER.decodeWithStream(passwordData.data)) {
99      return PayResult.FAIL;
100    }
101    return PayResult.SUCCESS;
102  }
103}
104
105let mPayServer = CreateOrGet(PayServer, TAG);
106
107export default mPayServer as PayServer;