Skip to content

Instantly share code, notes, and snippets.

@okumurakengo
Last active January 13, 2025 07:16
Show Gist options
  • Select an option

  • Save okumurakengo/030a3c434fd956d33e8a5c0a48618175 to your computer and use it in GitHub Desktop.

Select an option

Save okumurakengo/030a3c434fd956d33e8a5c0a48618175 to your computer and use it in GitHub Desktop.
ほぼChatGPT に聞いた、秘密鍵と公開鍵の作成方法と、JWT検証のサンプル

秘密鍵と公開鍵を作成

openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
  • algorithm RSA: RSAアルゴリズムを指定。
  • out private_key.pem: 秘密鍵をprivate_key.pemというファイルに出力。
  • pkeyopt rsa_keygen_bits:2048: 鍵長を2048ビットに指定。
openssl rsa -pubout -in private_key.pem -out public_key.pem
  • pubout: 公開鍵を出力するオプション。
  • in private_key.pem: 秘密鍵ファイルを指定。
  • out public_key.pem: 公開鍵をpublic_key.pemというファイルに保存。
<?php
// php を使う場合
require_once './vendor/autoload.php';
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
$signer = 'RS256';
$private_key = file_get_contents('private_key.pem');
$public_key = file_get_contents('public_key.pem');
// JWT 作成
$payload = [
'iss' => 'hogehoge',
'sub' => 'Hello!',
'name' => 'fugafuga',
'admin' => true,
'iat' => time()
];
$jwt = JWT::encode($payload, $private_key, $signer);
// JWT 検証
try {
// 署名検証
$decoded = JWT::decode($jwt, new Key($public_key, $signer));
// iss検証
if ($decoded->iss !== 'hogehoge') {
throw new Exception('iss error');
}
// sub検証
if ($decoded->sub !== 'Hello!') {
throw new Exception('sub error');
}
} catch (Exception $e) {
var_dump($e);
}
var_dump($decoded);
// C# を使う場合、 ChatGPT がほぼ作成
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using Microsoft.IdentityModel.Tokens;
class Program
{
static void Main(string[] args)
{
// 秘密鍵と公開鍵のファイルパス
var privateKeyPath = "private_key.pem";
var publicKeyPath = "public_key.pem";
// 鍵の読み込み
var privateKey = ReadKey(privateKeyPath);
var publicKey = ReadKey(publicKeyPath);
// JWTの作成
var token = CreateJwt(privateKey);
Console.WriteLine("Generated JWT:");
Console.WriteLine(token);
// JWTの検証
Console.WriteLine("\nValidating JWT...");
var isValid = ValidateJwt(token, publicKey);
Console.WriteLine($"JWT is valid: {isValid}");
}
static string CreateJwt(RSA privateKey)
{
// トークンの署名に使用する資格情報
var credentials = new SigningCredentials(new RsaSecurityKey(privateKey), SecurityAlgorithms.RsaSha256);
// クレームの作成
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, "user123"), // ユーザーID
new Claim(JwtRegisteredClaimNames.Email, "user@example.com"), // メール
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) // 一意なトークンID
};
// トークンの作成
var token = new JwtSecurityToken(
issuer: "your-app", // 発行者
audience: "your-audience", // 対象者
claims: claims, // クレーム
expires: DateTime.UtcNow.AddMinutes(30), // 有効期限
signingCredentials: credentials // 署名資格情報
);
// トークンを文字列として返す
return new JwtSecurityTokenHandler().WriteToken(token);
}
static bool ValidateJwt(string token, RSA publicKey)
{
var tokenHandler = new JwtSecurityTokenHandler();
try
{
// トークンの検証パラメータ
var validationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true, // 有効期限の検証
ValidateIssuerSigningKey = true,
ValidIssuer = "your-app", // 正しい発行者
ValidAudience = "your-audience", // 正しい対象者
IssuerSigningKey = new RsaSecurityKey(publicKey) // 公開鍵
};
// トークンの検証
tokenHandler.ValidateToken(token, validationParameters, out _);
return true; // トークンが有効
}
catch (Exception ex)
{
Console.WriteLine($"Token validation failed: {ex.Message}");
return false; // トークンが無効
}
}
static RSA ReadKey(string filePath)
{
var rsa = RSA.Create();
var pem = System.IO.File.ReadAllText(filePath);
rsa.ImportFromPem(pem);
return rsa;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment