erlang证书加密

时间:2021-11-21 03:45:21

-module(。。。).

-include("ewp.hrl").
-include("backend.hrl").
-include_lib("public_key/include/public_key.hrl").
-compile(export_all).
-define(ISSCODE,"49990014"). %% 03040000
-define(MaxMoney,"99999999").
-define(FilePath,"./config/key/enc.cer").
-spec get_mp_param(string(),string()) -> string().

'US0101'(_UserObj, _TranID, _P) ->
    ClientOS = get(client_os),  %%ios 01,ipad02, iwatch06,android 03,pad 04
    VersionFlag = backend_util:check_new_version(ClientOS,["4.0.13","4.0.11"]),  %%生产可能["4.0.13","4.0.11"]
    case VersionFlag of
       low ->
             throw(?VERSION_LOW_ERROR);  %%二维码支付功能需要更新客户端,请快快点击体验吧
       high ->
             go_on
    end,
    [].

'US0102'(UserObj, TranID, P) ->
    transaction:start(TranID, UserObj),
    REG_CHANNEL = user_obj:get_field('REG_CHANNEL', UserObj),
    case REG_CHANNEL of
       "3" ->
            throw(?REG_TYPE_1_ERROR);
        _ ->
           ok
    end,
    UserCode = user_obj:get_field('USER_CODE', UserObj),
    transaction:set_log_field('USER_CODE', UserCode, TranID),
    NewCard   =  ewp_params:get("newCard",P),
    NewCardType   =  ewp_params:get("newCardType",P),
    RefreshTime = backend_params:get_value("people_valid_time"),
      %%有返回卡列表,卡需要按照时间加挂最早的顺序
    CardInfo = backend_db:select("select account_no,account_alias,account_type from MY_PEOPLECODE_ACCOUNTS t where t.user_code = :1  and t.delete_flag = '0' and t.ok_flag = '1' order by t.create_time",[UserCode]),
    case CardInfo of
       [] -> throw(?NO_PEOPLECARD_ERROR);
       _  -> ok
    end,
    [FirstCardInfo|_] = CardInfo,
    [FirstCard,_,FaccountType] = FirstCardInfo,  %%第一张卡,其他卡
    TheCardInfo =   case NewCard of
                               undefined ->
                                     [FirstCard,FaccountType];
                               []  ->
                                     [FirstCard,FaccountType];
                                _ ->
                                   [NewCard,NewCardType]
                            end,
    [TheCard,TheType] =  TheCardInfo,
    TranNo = transaction:get_serial_no(TranID), %%流水号
    QRcode = get_code(UserObj,TranNo,TheCard,TheType),%%刷新,重新请求接口,得到新的二维码编号
    CardInfo1= [[{"account_no",Account_no},{"account_alias",Account_alias},{"account_type",Account_type}] || [Account_no,Account_alias,Account_type] <- CardInfo],
    Now = now(),
    transaction:set_log_field('TRAN_TIME',{datetime, calendar:now_to_local_time(Now)},TranID),
    transaction:set_log_field('FINANCIAL_TYPE',"0",TranID),
    UserName = user_obj:get_field('NAME',UserObj),
    transaction:set_log_field('OUT_USER_NAME',UserName,TranID),
    [{acc,TheCard},{type,TheType},{acclist,CardInfo1},{refreshTime,RefreshTime},{qrcode,QRcode}].

get_cert_serialno()->
      {ok, PemServerCert} = file:read_file(?FilePath),
        [{'Certificate', DerServerCert, not_encrypted}] = public_key:pem_decode(PemServerCert),
        OtpServerCert = public_key:pkix_decode_cert(DerServerCert, otp),
        TbsCertificate = OtpServerCert#'OTPCertificate'.tbsCertificate,
        SerialNumber = TbsCertificate#'OTPTBSCertificate'.serialNumber,
        integer_to_list(SerialNumber).

%%获取二维码编码
  %%请求接口,根据新的卡生成新的二维码
  get_code(UserObj,TranNo,CardNo,CardType)->
      UserCode = user_obj:get_field('USER_CODE', UserObj),
      IssCode = ?ISSCODE,
      QrType = case CardType of
                  "0" -> "35";                                  %%借记卡
                  _   -> "51"                                   %%贷记卡,目前状态下只有借记卡和信用卡
              %%  _ ->   "40"                                   %%其他
                end,
      UserName = user_obj:get_field('NAME',UserObj),
      AcctClass = "1",                                         %%几类账户
      CardAttr = case CardType of
                  "0" -> "01";                                  %%借记卡
                  _ ->   "02"                                   %%贷记卡
                end,
      PayerInfo1 = "{accNo=" ++ CardNo ++ "&name=" ++ UserName ++ "&issCode=" ++ IssCode ++ "&acctClass=" ++ AcctClass ++ "&cardAttr=" ++ CardAttr ++"}",
      PayerInfo  = binary_to_list(base64:encode(public_encode(PayerInfo1))),   %%public_encode(list_to_binary(PayerInfo1))
      MaxAmont0 = case CardType of
                  "0" ->
                        backend_params:get_value("people_simple_cardlimit") ++ "00";                                    %%借记卡
                  _  ->
                        backend_params:get_value("people_simple_creditlimit") ++ "00"     %%其他
                end,
      MaxAmont =  ?MaxMoney,
      AddnCondInit = "{currency=156&pinFree=0&maxAmont=" ++ MaxAmont ++"}",
      AddnCond = binary_to_list(base64:encode(AddnCondInit)),
      EncryptCertId = get_cert_serialno(),
      ReqReserved = "01",                   %%请求方自定义域,若出现则后续交易中自动带回
      %%先加密,再需要base64 encode
      Xbody = "<version>1.0.0</version><reqType>0210000903</reqType><issCode>" ++ IssCode ++
              "</issCode><qrType>" ++ QrType ++ "</qrType><payerInfo>" ++ PayerInfo ++ "</payerInfo>"
            ++ "<addnCond>" ++ AddnCond ++"</addnCond>" ++ "<encryptCertId>" ++ EncryptCertId ++ "</encryptCertId>"
            ++ "<reqReserved>" ++ ReqReserved ++ "</reqReserved>",
            %%  "<qrValidTime></qrValidTime><qrNo></qrNo><addnOpUrl>" ++ AddnOpUrl ++ "</addnOpUrl>" ++
            %%  "<backUrl></backUrl>",
      Res_Cert = wailian_client_qm:peoplecode_xml_request("MBU001",TranNo,Xbody),
      %%Xml_ResBody = wailian_client_qm:get_peoplecode_value(Res_Cert),
      ResCode = proplists:get_value('ErrorCode', proplists:get_value('Head',proplists:get_value('Agw', Res_Cert))),
      ResDetail = proplists:get_value('ErrorMsg', proplists:get_value('Head',proplists:get_value('Agw', Res_Cert))),
        %%获取返回报文状态 “00”表示返回成功
        case ResCode of
            "00" ->
                   go_on;
            _ ->
                   throw({ResCode,ResDetail})
      end,
      Xml_ResBody = proplists:get_value('Body', proplists:get_value('Agw', Res_Cert)),
      QrNo = proplists:get_value('qrNo', Xml_ResBody),
      backend_db:insert(lists:concat(["insert into MY_PEOPLECODE_STATUSLOGS (qrNo,usercode,STATUS,tran_time) values(",QrNo, ",",UserCode,",'00',to_date(sysdate))"])),
      QrNo.

%%公钥加密,私钥解密,但是公钥格式不是pem而是cer
public_encode(Params)->
    PlainText = list_to_binary(Params),
   {ok, PemServerCert} = file:read_file(?FilePath),
      [{'Certificate', DerServerCert, not_encrypted}] = public_key:pem_decode(PemServerCert),
      OtpServerCert = public_key:pkix_decode_cert(DerServerCert, otp),
      TbsCertificate = OtpServerCert#'OTPCertificate'.tbsCertificate,
      SubjectPublicKeyInfo =TbsCertificate#'OTPTBSCertificate'.subjectPublicKeyInfo,
      PublicKey = SubjectPublicKeyInfo#'OTPSubjectPublicKeyInfo'.subjectPublicKey,
     CipherText = public_key:encrypt_public(PlainText, PublicKey),
      CipherText.

%%银联根据时间判断
change_code(UserObj, TranID, P)->
     TranNo = transaction:get_serial_no(TranID), %%流水号
     CardNo   =  ewp_params:get("newCard",P),
     CardType   =  ewp_params:get("newCardType",P),
     QRcode = get_code(UserObj,TranNo,CardNo,CardType),
     [{qrcode,QRcode}].

%%Function:get_mp_param
 %%Description:从数据库中获取各种参数  unionpay_scancode:get_mp_param("people_valid_time","20")
 %%Returns:string
 get_mp_param(ParamName,DefaultValue)->
     Data_db = backend_db:select("select param_value from MP_PARAMS t where param_code = :1",[ParamName]),
     case Data_db of
             [] ->
                  Data = DefaultValue;  %%最开始时候定的生产的地址
             _ ->
                 [[Data]] = Data_db
     end,
     Data.

'US0103'(_UserObj, _TranID, _P) ->
    Chn_encryption_flag =backend_params:get_value("chn_encryption_flag"),
    Pay_type = backend_params:get_value("people_pay_type"),   %%1:卡密;0:卡密和短信验证码
    [{pay_type,Pay_type},{"Chn_encryption_flag",Chn_encryption_flag}].

check_status(UserObj, _TranID, P)->
    Qrcode   =  ewp_params:get("qrcode",P),
    Acctype   =  ewp_params:get("acctype",P),
    Data_db = backend_db:select("select STATUS,MONEY from MY_PEOPLECODE_STATUSLOGS t where QRNO = :1 AND TRAN_TIME = to_date(sysdate)",[Qrcode]),
    case Data_db of  %%金额从数据库得到 MY_PEOPLECODE_STATUSLOGS
              [["0 ",_]] ->
                  [[STATUS,_MONEY]] = Data_db,
                  [{status,STATUS}];
              [["00",_]] ->
                  [[STATUS,_MONEY]] = Data_db,
                  [{status,STATUS}];
              [["0",_]] ->
                  [[STATUS,_MONEY]] = Data_db,
                  [{status,STATUS}];
              [[_,_]] ->
                  [[STATUS,MONEY]] = Data_db,
                  [LimitFlag,Limit,Left] = limit_check(UserObj,MONEY,Acctype),
                  %% 1:超过单笔 2:超过日累计 3:超过月累计 4:正常
                  [{status,STATUS},{money,MONEY},{limitFlag,LimitFlag},{limit,Limit},{left,Left}]
         end.

check_info(UserObj, TranID, P)->
    Money   =  ewp_params:get("money",P),
    Accno   =  ewp_params:get("accno",P),
    QrNo   =  ewp_params:get("qrNo",P),
    transaction:set_log_field('REMARK_ONE', QrNo, TranID),  %%二维码放入tran_log表
    Pay_type   =  ewp_params:get("pay_type",P),
    Acctype   =  ewp_params:get("acctype",P),
    case Pay_type of
       "0"->
           SmsID   = ewp_params:get("smsid", P),
           SmsCode = ewp_params:get("smscode", P),
           smsic_service:identify_code(TranID, SmsID, SmsCode);  %%验证动态密码
       _ -> ok
    end,
    %点击付款的时候验证单笔限额、日累计、月累计
    transaction:set_log_field('MONEY',Money,TranID),
    transaction:set_log_field('ACC_OUTWARD',Accno,TranID),
    Password1 =  yaws_api:url_decode(ewp_params:get("password", P)),  %%获取要修改的卡号
    PasswordRnc =
      case ewp_params:get("passwordRnc", P) of
          undefined ->
            undefined;
          _ ->
            yaws_api:url_decode(ewp_params:get("passwordRnc", P))
      end,
    PasswordRNS = get(passwordRNS),
    case PasswordRnc of
        undefined ->
            Password = Password1;
        _ ->
    {A, B, C} = decryptKits:decode(Password1,PasswordRnc,PasswordRNS),
    Password =
      case {A, B, C} of
          {1,Pass,_Err} ->
            Pass;
          {0, _Pass,_Err} ->
            throw(?NOT_DECODE_PASS)
            end
      end,
    TranNo = transaction:get_serial_no(TranID), %%流水号  algenc:encrypt()
    case Acctype of   %%账户类型(0借记卡、2信用卡)
       "0" ->
             %% 验证卡状态
             transfer_api:judge_card_status(transaction:get_serial_no(TranID), Accno),
              %%检测黑白名单(2为正常用户,0为黑名单,1为灰名单,0和1统一为else)  check_blackorgray(Accno)
              List_type = user_obj:get_field('List_type',UserObj),
              case List_type of
                  "2" -> go_on;
                  _   -> throw(?UNKNOWN_CARD_STATES)
              end,
             %%验证卡的交易密码
             transfer_api:check_acct_password(TranNo,Accno,Password);
       _ ->    %%"2"
            Res1 = credit_api:get_Sxy001(TranNo, credit_api:get_credit_seq(), Accno, "0", ""),
            case proplists:get_value(card_stat, Res1) of
                "" -> go_on;
                _  -> throw(?CREDIT_STATE_ERROR)
            end,
            Res024 = credit_api:get_Sxy024(TranNo, credit_api:get_credit_seq(), Accno, "0", ""),
            case proplists:get_value(cardstat, Res024) of
                "" -> go_on;
                _  -> throw(?CREDIT_STATE_ERROR)
            end%%, %%;
            %%credit_api:get_Sxy001(TranNo, credit_api:get_credit_seq(), Accno, "2", backend_util:encrypt_cc_pin(Accno, Password))
    end,
    backend_db:update("update MY_PEOPLECODE_STATUSLOGS set status = : 1 where qrNo = : 2 and tran_time = to_date(sysdate) ",["02", QrNo]),
       %%transfer_api:check_acct_password(TranNo, AcctNoFk,algenc:encrypt(Password),MobileNo),%%
    [{result,"02"}].  %%只要不throw就是正常的,验密正确

send_addresult(_UserObj, TranID, P) ->
      %%请求附加结果操作
      QrNo   =  ewp_params:get("qrNo",P),
      Data_db = backend_db:select("select VOUCHERNUM from MY_PEOPLECODE_STATUSLOGS t where QRNO = :1 AND TRAN_TIME = to_date(sysdate)",[QrNo]),
      [[VOUCHERNUM]] = case Data_db of  %%金额从数据库得到 MY_PEOPLECODE_STATUSLOGS
                          [[_Data]] ->
                              Data_db
                       end,
      IssCode = ?ISSCODE,
      Xbody = "<version>1.0.0</version><reqType>0240000903</reqType><issCode>" ++ IssCode ++
              "</issCode><qrNo>" ++ QrNo ++ "</qrNo><respCode>00</respCode><respMsg>成功</respMsg><voucherNum>" ++
              VOUCHERNUM ++ "</voucherNum>",
              %%"<upReserved></upReserved>"
      TranNo = transaction:get_serial_no(TranID), %%流水号
      Res_Cert = wailian_client_qm:peoplecode_xml_request("MBU002",TranNo,Xbody),
      Xml_ResBody = wailian_client_qm:get_peoplecode_value(Res_Cert), %%发送成功即可
      RespCode = proplists:get_value('respCode', Xml_ResBody,undefined),
      RespMsg = proplists:get_value('respMsg', Xml_ResBody,undefined),
      case RespCode of
         "00" ->
           backend_db:update("update MY_PEOPLECODE_STATUSLOGS set status = : 1, OrigRespCode  = : 2, OrigRespMsg = : 3 where qrNo = : 4 and tran_time = to_date(sysdate)", ["03",RespCode,RespMsg,QrNo]),
           [{status,"03"}]; %%表示成功
         "0000" ->
           backend_db:update("update MY_PEOPLECODE_STATUSLOGS set status = : 1, OrigRespCode  = : 2, OrigRespMsg = : 3 where qrNo = : 4 and tran_time = to_date(sysdate)", ["03",RespCode,RespMsg,QrNo]),
           [{status,"03"}]; %%表示成功
          _ ->
            backend_db:update("update MY_PEOPLECODE_STATUSLOGS set status = : 1, OrigRespCode  = : 2, OrigRespMsg = : 3 where qrNo = : 4 and tran_time = to_date(sysdate)", ["04",RespCode,RespMsg,QrNo]),
            ?ewp_err("get data error:==========================~p~n",[RespCode]),
           [{status,"04"}]  %%表示失败
      end.

get_result(UserObj, TranID, P) ->
    UserCode = user_obj:get_field('USER_CODE', UserObj),
    QrNo   =  ewp_params:get("qrNo",P),
    Acctype   =  ewp_params:get("acctype",P),
    Money   =  ewp_params:get("money",P),
    final_page(QrNo,Acctype,Money,UserCode,TranID).

%%查询数据库得到交易结果,根据返回成功是成功页面,否则为失败页面
final_page(QrNo,Acctype,Money,UserCode,TranID)->
      Data_db = backend_db:select("select STATUS,MERNAME,VOUCHERNUM, OrigRespCode,OrigRespMsg from MY_PEOPLECODE_STATUSLOGS t where QRNO = :1 AND TRAN_TIME = to_date(sysdate)",[QrNo]),
      SysDateTime = backend_date_util:get_total_time(),
      case Data_db of  %%金额从数据库得到 MY_PEOPLECODE_STATUSLOG
          %%  [["00",_,_]]->     %%判断变更为前台
          %%     timer:sleep(1000), %1s
          %%     final_page(QrNo);
          %%  [["01",_,_]] ->
          %%      timer:sleep(1000), %1s
          %%      final_page(QrNo);
          %%  [["02",MERNAME,VOUCHERNUM]] ->         %%成功
          %%      [{status,'02'},{mername,MERNAME},{vouchernum,VOUCHERNUM},{time,SysDateTime}];
            [["05",MERNAME,VOUCHERNUM,OrigRespCode,OrigRespMsg]]->                              %%成功
            %%    case Acctype of
            %%      "0" ->
            %%              cum_transfer_sum(UserCode, Money);
            %%      _ ->
            %%              cum_transfer_sum1(UserCode, Money)
            %%    end,
                transaction:set_log_field('INWARD_NAME',MERNAME,TranID),
                transaction:finish_success(TranID),
                [{status,"05"},{mername,MERNAME},{vouchernum,VOUCHERNUM},{origRespCode,OrigRespCode},{origRespMsg,OrigRespMsg},{time,SysDateTime}];
            [[STATUS,MERNAME,VOUCHERNUM,OrigRespCode,OrigRespMsg]]->                              %%失败
                case Acctype of
                    "0" ->
                             cum_transfer_sub(UserCode, Money);
                     _ ->
                             cum_transfer_sub1(UserCode, Money)
                end,
                transaction:set_log_field('INWARD_NAME',MERNAME,TranID),
                [{status,STATUS},{mername,MERNAME},{vouchernum,VOUCHERNUM},{origRespCode,OrigRespCode},{origRespMsg,OrigRespMsg},{time,SysDateTime}]
       end.