いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-162 (crypto/tls/generate_cert.go を使ってオレオレ証明書作成)

概要

知らなかったので、忘れないうちにメモメモ。

Goの標準ライブラリの中に crypto/tls/generate_cert.go というファイルがあります。

これを go run で起動してやると、https サーバに必要な pem ファイルを生成してくれます。

当然、正規の証明書ではないので、ブラウザで開くと警告出るのですが、画面は表示できます。

WebRTCとかの開発をやっていたり、スマホ側でPC側のWebアプリを開いたりする際に https じゃないと見れない状況とかがあるので、何気にとても便利ですねーこれ。

やり方はすごく簡単です。

cert.pemとkey.pemを生成

以下のコマンドを実行すると、カレントディレクトリに cert.pemkey.pem が生成されます。

$ go run $(go env GOROOT)/src/crypto/tls/generate_cert.go -rsa-bits 2048 -host localhost

httpsサーバを起動

http.ListenAndServe とする部分を http.ListenAndServeTLS とするだけです。

/*
Go の標準パッケージだけを使って HTTPS サーバをローカルで立てるサンプル

REFERENCES:
   - https://pkg.go.dev/net/http
   - https://hodalog.com/generate-self-signed-certificate-using-by-golang/
   - https://fm-cowkey.hatenablog.com/entry/2018/01/27/154721
   - https://code-database.com/knowledges/87
   - https://zenn.dev/tomi/articles/2020-10-02-go-web3
*/
package main

import (
    "fmt"
    "log"
    "net/http"
    "os"
)

func main() {
    ret := 0

    if err := run(); err != nil {
        fmt.Fprintf(os.Stderr, "%s\n", err)
        ret = 1
    }

    os.Exit(ret)
}

func run() error {
    //
    // Go の標準パッケージの中にオレオレ証明書を作成するためのソースがある
    // 以下の様にして呼び出せる
    //
    // $ $(go env GOROOT)/src/crypto/tls/generate_cert.go -rsa-bits 2048 -host localhost
    //
    // 実行すると、key.pem と cert.pem ファイルが生成される
    //
    // 後は、このファイルを使ってサーバーを起動するだけとなる。
    // ただし、正式な証明書ではないため、そのままChromeで開くと証明書エラーが表示されるので
    //   chrome://flags/#allow-insecure-localhost
    // をブラウザのURL欄に入力し
    //   Allow invalid certificates for resources loaded from localhost
    // の項目を Enabled に設定する。
    //
    http.Handle("/", http.FileServer(http.Dir("html/")))
    log.Println(http.ListenAndServeTLS(":8888", "./cert.pem", "./key.pem", nil))

    return nil
}

サンプルのHTML

スマホ側でカメラ起動するだけのサンプル。スマホ側から見る場合、WebRTCを使うのでhttpsじゃないと動いてくれません。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>WebRTC</title>
    <style>
        html {
            height: 100%;
        }
        
        body {
            height: 100%;
            margin: 0;
        }
        
        main {
            height: 100%;
            background: #000;
        }
        
        video {
            object-fit: fill;
        }
    </style>
</head>

<body>
    <main>
        <video id="video" autoplay muted playsinline></video>
    </main>
    <script>
        const _constraints = {
            audio: false,
            video: {
                facingMode: 'environment'
            }
        };

        const _load = (constraints) => {
            const device = navigator.mediaDevices;
            device.getUserMedia(constraints).then((stream) => {
                document.getElementById('video').srcObject = stream;
            });
        }

        _load(_constraints);
    </script>
</body>

</html>

起動

以下のように実行してから、スマホからアクセスすると証明書がillegalって警告でるけどそのまま進めば画面でます。

$ go run $(go env GOROOT)/src/crypto/tls/generate_cert.go -rsa-bits 2048 -host localhost
$ go run .

面倒なので go-task 用の Taskfile.yml にまとめると以下な感じ。

# https://github.com/go-task/task
version: '3'

tasks:
  default:
    deps:
      - task: gen
  gen:
    cmds:
      - go run $(go env GOROOT)/src/crypto/tls/generate_cert.go -rsa-bits 2048 -host localhost
  run:
    deps:
      - task: gen
    cmds:
      - go run .
$ task run

で起動。

サンプル

サンプルを Github 上にアップしておきました。ご参考まで。

github.com

参考資料


過去の記事については、以下のページからご参照下さい。

  • いろいろ備忘録日記まとめ

devlights.github.io

サンプルコードは、以下の場所で公開しています。

  • いろいろ備忘録日記サンプルソース置き場

github.com

github.com

github.com