記事ディレクトリ
私は以前 HTTPS 証明書について 2 つの記事を書きました。1 つはローカルの自己署名証明書に関するもので、もう 1 つはdiafygi/gethttpsforfree
Let's Encrypt が無料のワイルドカード証明書のサポートを開始したときに Web ページから証明書を申請することに関するものです。手順は非常に面倒です。2022 年 9 月に書きました。私は ACME クライアントの非常にシンプルな Web バージョンACME-HTML-Web-Browser-Client を開発し、GitHubとGiteeでオープンソース化しました。
Let's Encrypt
ソース コード全体は静的な HTML Web ページ ファイルのみであり、ローカルに直接保存することも、オンライン Web サイトを通じて使用することもできます。ACME プロトコルをサポートする認証局からのHTTPS ( 、 )ZeroSSL
用の SSL/TLS ドメイン名証明書の無料申請をサポートしています。など、複数のドメイン名とワイルドカード汎ドメイン名をサポートします。最新のブラウザで操作するだけで、オペレーティング システム環境に関係なく、プレーン テキストで PEM 形式のドメイン名証明書を取得できます。ソフトウェアをダウンロードしてインストールする必要はありません。登録とログインは純粋な手動操作であり、「証明書の申請」のみに焦点を当てます。RSA
ECC/ECDSA
証明書の有効期限のリスクに関するリマインダー:この Web クライアントは純粋に手動でのみ操作でき、自動更新はサポートされていないため、証明書の有効期限が切れる前に新しい証明書を再生成して申請する必要があります (無料の証明書は通常 90 日間有効であり、その時点で操作を繰り返す必要があります)、または acme.sh などのクライアントを使用して更新を自動化します。
オープンソース プロジェクトの起源
私は主に Windows をよく使用しており、証明書を取得するために純粋に手動操作を行うことは気にしません、またはそれを好みますが、ACME の公式クライアント リストには、必要なものを簡単に提供できるものはほとんどありません。特定のオペレーティング システム環境に依存すること、特定の動作環境、独自のコード開発を記述する必要があり、一部の製品にはオンライン実稼働環境をバンドルする必要があります。私の要求は単純に証明書ファイルを取得することですが、それには一連のバケットが必要です。集中するのは難しい 証明書を取得するという 1 つのことにのみ申請してください。
Bash
一般的な ACME クライアントには、スクリプト環境が必要か、さまざまな開発言語のソース コードやサードパーティ ライブラリが独自のコードを記述する必要があります。Let's Encrypt の以前のリストには、Web バージョンを提供するクライアントのリストも含まれています ( Iその中で見つけましたgethttpsforfree
)、このため、公式 Web サイトには“一些浏览器内 ACME 客户端可用,但我们未在此处列出它们,因为它们鼓励手动续订工作流程,这会导致糟糕的用户体验并增加错过续订的风险”
Web クライアントのリストが表示されなくなりました。非常に残念です。たとえば、直接使用できる Windows をサポートするデスクトップ プログラムもいくつかありますが、それは困難です。win-acme
ドキュメントを読んでから始めましょう。一部のクライアントや Web サイトでは登録が必要です。使用するにはアカウントにログインし、秘密キーの管理にも役立ちます (サーバーに保存されているため、アドレス帳を削除するのが待ちきれません) 。、はぁ~ばぁ~~
長い間、私はfszlin/certes
この .Net ライブラリを使用して証明書を発行してきました。C# でコンソール プログラムを作成しました。プログラムをダブルクリックすると、直接検証段階に進みます。DNS 検証レコードを構成した後、証明書ファイルを申請できます。 , しかし、他の人が使用する必要があります。面倒です。C# コードを変更する必要があります。さらに重要なことに、EXE プログラムには信頼性の問題があり、EXE プログラムをダブルクリックするのは多くのリスクが必要です。Web バージョンはWebページ自体が全く異なり、オープン性が高い コードに追加がないか確認できる Webページは当然UIに適している スクリプトコンソールプログラムよりも人間とコンピュータのインタラクションの親しみやすさがはるかに高いサーバー上での証明書の自動更新や自動展開が必要ない方には、Webページ上でオンライン申請するのが最も理想的な運用方法で、例えばWebページのソースコードを確認でき、フローを完全に監視できdiafygi/gethttpsforfree
ます。ブラウザ コンソールを介してネットワーク データを取得する方法です。これが最もシンプルで信頼性が高くなります。この Web ページもオープン ソースですが、操作が面倒です。また、issues/164 についても触れました。署名操作を簡素化するために使用している方法です。
RSA
私の期待を満たし、最新のブラウザーによる暗号化、署名の直接サポートに依存して操作が簡単な、 ACME クライアントの Web バージョンを使用できるようにするためECC
、**そこで、自分で作成することにしました。**幸いなことに、私はこれまでに暗号に関する基本的な知識を蓄積しており、このクライアントを作成する際に知識の死角はなく、すべての HTML コードを正常に作成し、オープン ソースにすることができました。
プロジェクトアドレス
GitHub:
https://github.com/xiangyuecn/ACME-HTML-Web-Browser-Client
Gitee:
https://gitee.com/xiangyuecn/ACME-HTML-Web-Browser-Client
このクライアントをオンラインで使用します:
国内访问gitee.io:
https://xiangyuecn.gitee.io/acme-html-web-browser-client/ACME-HTML-Web-Browser-Client.html
不太稳定github.io:
https://xiangyuecn.github.io/ACME-HTML - Web ブラウザ クライアント/ACME-HTML-Web ブラウザ クライアント.html
手順
完全な操作プロセスは次のとおりです。手順に従って証明書ファイルを申請してください。この記事の写真に示されているデータはデモンストレーション目的であり、実際のデータではありません。
ステップ 1: Let's Encrypt、ZeroSSL、またはその他の認証局を選択する
上記のプロジェクト アドレスに従って、この Web ページ クライアントを開きます (唯一の HTML ファイルをダウンロードして保存し、ダブルクリックして開くか、オンライン Web サイトを使用します)。ACME プロトコルをサポートする認証局である限り、次のことができます。対応するアドレスを入力します。現在デフォルトで提供されているLet's Encrypt
2ZeroSSL
つの会社のアドレスは、ニーズに応じて直接選択できます。
異なる認証局で必要な操作は必ずしも同じではありません。プロンプトに従って操作してください。ACME サービスはブラウザのサポートにあまり適しておらず、クロスドメインの問題があるため、直接 2 番目のステップに進みます
Let's Encrypt
。ZeroSSL
さらにいくつかの操作 (ソース コードをサービス アドレス ページ内で実行し、クロスオリジンの問題を排除します) にコピーします。
ステップ 2: 証明書の構成、ドメイン名を入力します。
Web ページの 2 番目のステップでは、証明書を申請する必要があるドメイン名 (複数のドメイン名とワイルドカード文字がサポートされています)、およびキーとその他の情報の構成を入力します。構成はさまざまな方法で入力する必要があります。認証局は必ずしも同じではありませんので、画面の指示に従って操作してください。
ドメイン名リストを入力します。たとえば、ドメイン名 の証明書を申請する場合はtest123.com
、ワイルドカードを使用してドメイン名を直接入力できます。test123.com, *.test123.com
申請する証明書は、次のようなドメイン名で使用できます。test123.com
、、www.test123.com
など。app.test123.com
注: このドメイン名を使用する必要がある場合は、次のようなものをxxx.app.test123.com
追加する必要があります。*.app.test123.com
証明書の秘密キー:直接クリックして新しい RSA 秘密キーを作成することをお勧めします。
ACME アカウントの秘密鍵:以前に申請したことがある場合は、以前に使用した秘密鍵を入力することを推奨します。申請していない場合は、同様の方法で新しい RSA 秘密鍵を作成します。
ACME 連絡先電子メール:頻繁に使用する電子メールを入力すると、証明書の有効期限が切れる前に証明書を更新するよう通知する電子メールが認証局から送信されます。電子メールをランダムに入力すると、リマインダーは受信されません。
EAB 資格情報:一部の ACME サービスでは、ZeroSSL などの外部アカウント バインディング資格情報 ( 、 、 ) が必要です。この資格情報は、ZeroSSL 管理コンソールの開発者で取得できるため、最初に ZeroSSL アカウントを登録する必要があります。Let's Encrypt ではこれは行われExternal Account Binding
ませexternalAccountBinding
ん。externalAccountRequired
オプション。
ステップ 3: ドメイン所有権の検証を完了する
Web ページに表示される 3 番目のステップの内容に従って、ドメイン名ごとに適切なドメイン名所有権検証方法を構成します。一般的な検証方法には、検証のために DNS 解決で TXT レコードを構成する、検証のためにサーバーにファイルをアップロードする、ワイルドカードが含まれます。通常、ドメイン名は DNS 検証のみをサポートします。すべての構成が完了した後に検証を開始し、検証に合格した後に証明書をダウンロードできます。
DNS 検証方法を使用することをお勧めします。ドメイン名解決管理のバックグラウンドにログインし、ドメイン名解決でサブドメイン名のTXTレコードを入力するだけです。これはシンプルで高速であり、複雑ではありません。間違いを犯しやすいため*.test123.com
、_acme-challenge.test123.com
ドメイン名の下に複数の TXT レコードを追加できます)。
ファイルをアップロードして検証します。この方法は推奨されません。サーバーが必要です。そうでないと、ACME がファイルにアクセスできない場合、検証は失敗します。アップロードされたファイルに正常にアクセスできるようにするには、サーバーの構成が必要になる場合があります。 (解決策を検索して自分で行ってください)、検証を開始する前に、URL アドレスをテストし、正常にアクセスできることを確認します。
ステップ 4: 証明書 PEM ファイルをダウンロードして保存する
ドメイン名の所有権の検証に合格すると、Web ページに 4 番目のステップが表示され、証明書ファイルのダウンロードが提供され、ダウンロードして保存します。ダウンロードするファイルは 3 つあります (すべてプレーン テキストであり、メモ帳で開くことができます)。
- 証明書ファイル (完全な証明書チェーンを含む)
- 証明書の秘密鍵ファイル
- ログ記録ファイル。次回適用時にこのファイルをページに直接ドラッグ アンド ドロップすると、同じ設定が自動的に入力されます。
証明書ファイルのサフィックスはまたは に.pem
変更できるため、Windows で証明書をダブルクリックして開いて表示できます。.crt
.cer
最後に、ダウンロードして保存した証明書と秘密キーを Web サイトに設定します システムプログラムごとに設定方法が異なりますので、対応する設定方法をご自身で見つけてください。
ソースコード内のいくつかの再生可能なコード
ブラウザーでRSA
署名操作を実装するためにECC
、ソース コードは純粋な JS コードで実装されます。
PKCS#1
分析、PEM形式の公開鍵と秘密鍵PKCS#8
解析と生成、PEM形式の公開鍵と秘密鍵PKCS#10
PEM形式証明書要求CSRファイル(Certification Request)の生成
対応する関数はこのクライアントのオブジェクトにカプセル化されておりX509
、X509.CreateCSR を使用して CSR を生成し、X509.KeyGenerate を使用して PEM 形式のキーを作成し、X509.KeyParse を使用して PEM 形式のキーを解析し、X509.KeyExport を使用して PEM 形式のキーをエクスポートします。
これらの関数は、対応する標準に従って js コードを使用してバイナリ レベルで実装され、バイナリ データ操作はASN1
オブジェクトにカプセル化されます。ASN.1 標準のバイナリ解析とパッケージ化が実装され、ASN1.ParsePEM メソッドを使用して任意の PEM 形式を解析できます。キーまたは証明書。
この Web ページ クライアントを開いて、ブラウザ コンソールで次のコードを実行して確認してください。
console.log("生成一个512位的RSA私钥 PKCS#8:");
privateKey=await new Promise(function(resolve,reject){
X509.KeyGenerate("RSA", 512, function(pem){
resolve(pem)}, function(err){
reject(new Error(err))})
});
console.log(privateKey);
console.log("解析一个pem格式密钥:");
keyInfo=await new Promise(function(resolve,reject){
X509.KeyParse(privateKey, function(info){
resolve(info)}, function(err){
reject(new Error(err))})
});
console.log(keyInfo);
console.log("导出私钥的公钥 PKCS#8:");
publicKey=X509.KeyExport(keyInfo, true);
console.log(publicKey);
console.log("用私钥创建一个证书请求CSR PKCS#10:");
csr=await new Promise(function(resolve,reject){
X509.CreateCSR(keyInfo, "test123.com"
, ["test.com","*.test.com","*.app.test.com","test123.com","*.test123.com"]
, function(csr){
resolve(csr)}, function(err){
reject(new Error(err))})
});
console.log(csr);
console.log("用ASN1解析CSR得到二进制结构:");
csrASN1=ASN1.ParsePEM(csr);
console.log(csrASN1);
console.log("用ASN1解析私钥得到二进制结构:");
privateKeyASN1=ASN1.ParsePEM(privateKey);
console.log(privateKeyASN1);
console.log("用ASN1解析公钥得到二进制结构:");
publicKeyASN1=ASN1.ParsePEM(publicKey);
console.log(publicKeyASN1);
【終わり】