ホームページ  >  記事  >  バックエンド開発  >  PHP を使用して SHA1withRSA 署名、暗号化、検証を実装する

PHP を使用して SHA1withRSA 署名、暗号化、検証を実装する

little bottle
little bottle転載
2019-04-18 11:19:179518ブラウズ

PHP の専門家がインターネット上で共有している PHP 署名暗号化コードを見つけましたので、共有したいと思います。ご興味がございましたら、ぜひお越しください。

概念の説明:

SHA1 セキュア ハッシュ アルゴリズムは、主にデジタル署名標準で定義されているデジタル署名アルゴリズムに適用されます。

RSA は、現在最も影響力のある公開キー暗号化アルゴリズムです。これまでに知られているほとんどのパスワード攻撃に対抗でき、公開キー データ暗号化標準として ISO によって推奨されています。

SHA1WithRSA: 署名には SHA アルゴリズムを使用し、暗号化には RSA アルゴリズムを使用します。

ビジネス要件:

各署名によって組み立てられたコンテンツは、フィールド名の辞書の昇順にソートされて接続されます

最初に署名が必要なコンテンツを組み立てます:

/**
     * 拼接需要签名的内容
     * Author: Tao.
     *
     * @param array $data 需签名的字段内容
     * 
     * @return string
     */     
    public static function getSign($data)
    {
        foreach ($data as $k => $v) {
            $Parameters[$k] = $v;
        }
        //按字典序排序参数
        ksort($Parameters);
        $sign = '';
        foreach ($Parameters as $k => $v) {
            $sign .= $k . "=" . $v . "&";
        }
        $sign = '&' . rtrim($sign, '&');
        return $sign;
    }

署名文字列は次のとおりです:
&amount=金額値&ccy=ccy値&merchantId=merchantId値¬ifyUrl=notifyUrl値&orderId=orderId値&payeeAcctNo=payeeAcctNo値(プレーンテキスト)。

ビジネス ニーズに応じて、署名コンテンツの前にアンパサンドを結合するかどうかを選択できることに注意してください。

次に、秘密鍵の署名を生成します:

/**
     * 秘钥加密
     * Author: Tao.
     *
     * @param string $data 之前生成好的需加密内容
     * @param $key 私钥证书位置(.pfx文件)
     * @param string $pwd 证书密码
     *
     * @return string
     */
    public static function SHA1withRSA($data, $key,$pwd)
    {
        openssl_pkcs12_read(file_get_contents($key), $certs, $pwd); 
        if (!$certs) return;
        $signature = '';
        openssl_sign($data, $signature, $certs['pkey']);
        return bin2hex($signature);  
    }

サードパーティ企業は 16 進数への変換を必要とするため、必要に応じて bin2hex() または Base64_encode() を選択できます。

ここで注意すべき点は、ビジネス ニーズに応じて、署名されたコンテンツの大文字と小文字を区別する必要があるかどうかです。

署名されたコンテンツは小文字である必要があり、strtoupper() を使用して大文字に変換できます。

上記は、誰でも使えるようにまとめた秘密鍵暗号化方式です。

ただし、このビジネスでは、銀行カード番号を RSA 公開キーで暗号化する必要もあります。
公開キーを取得する方法は次のとおりです:
ここでは、相手のプラットフォーム証明書 (.cer ファイル) の公開キーを取得します。


/**
     * 获取公钥
     * Author: Tao.
     *
     * @param $path //公钥证书位置 (.cer文件)
     *
     * @return mixed
     * @throws \Exception
     */
    public static function loadCert($path)
    {
        $file = file_get_contents($path);
        if (!$file) {
            throw new \Exception('loadx509Cert::file_get_contents ERROR');
        }

        $cert = chunk_split(base64_encode($file), 64, "\n");
        $cert = "-----BEGIN CERTIFICATE-----\n" . $cert . "-----END CERTIFICATE-----\n";

        $res = openssl_pkey_get_public($cert);
        $detail = openssl_pkey_get_details($res);
        openssl_free_key($res);

        if (!$detail) {
            throw new \Exception('loadX509Cert::openssl_pkey_get_details ERROR');
        }
        return $detail['key'];
    }

    /**
     * 公钥加密
     * Author: Tao.
     * 
     * @param $pubPath  //公钥证书位置 (.cer文件)
     * @param string $bankCode //银行卡号
     * 
     * @return string
     */
    public static function rsa_encode($bankCode,$pubPath)
    {
        $pubkey = self::loadCert($pubPath);
        $encrypt_data = '';
        openssl_public_encrypt($bankCode, $encrypt_data, $pubkey);
        $encrypt_data = base64_encode($encrypt_data);
        return $encrypt_data;
    }

秘密キーが bin2hex() である理由を尋ねる必要があります。公開鍵はbase64_encode()に変更されます。理由がわかりません。尋ねると、16 ビットであると言われましたが、署名の要求は失敗し続けました。64 ビットに変更したところ、成功しました。相手は書類が古すぎて忘れられていると言いました。 。必要に応じて選択してください

最終的なコールバック結果の署名検証

まず、コールバック データ内の組み立てられた署名フィールドの内容を取り出し、上記の getSign() メソッドに従って並べ替えます。 。
その後、確認してください:

/**
     * 验证返回的签名是否正确
     *
     * @param string $data 要验证的签名原文
     * @param string $signature 签名内容
      *@param $pubPath  公钥证书位置 (.cer文件)
     *
     * @return bool
     */
    public static function verifyRespondSign($data, $signature,$pubPath)
    {
        $keys = self::loadCert($pubPath);
        $signature = hex2bin($signature);
        $ok = openssl_verify($data, $signature, $keys);
        if ($ok == 1) {
            return true;
        }
        return false;
    }

お役に立てば幸いです。何か間違っている場合は、指摘して修正し、お互いに学び合ってください。関連チュートリアル: PHP ビデオ チュートリアル

以上がPHP を使用して SHA1withRSA 署名、暗号化、検証を実装するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcnblogs.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。