Skip to content

Instantly share code, notes, and snippets.

@gurimusan
Created March 11, 2016 06:01
Show Gist options
  • Save gurimusan/99a114646099718e9ce8 to your computer and use it in GitHub Desktop.
Save gurimusan/99a114646099718e9ce8 to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
import base64
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicNumbers
"""
================================================
generate rsa private key.
================================================
from cryptography.hazmat.backends.openssl import backend
public_exponent = int(b'0x'+base64.urlsafe_b64decode(b'MTAwMDE='), 16)
pkey = backend.generate_rsa_private_key(public_exponent, 1024)
pkey.private_bytes(serialization.Encoding.PEM, serialization.PrivateFormat.PKCS8, serialization.NoEncryption())
"""
"""
2048ビット以上の鍵長は、このアルゴリズムを使用する必要があります。
次のようにRSA、SHA-256デジタル署名が生成されます。
1. RSASSA-PKCS1-v1_5の-SIGNと希望秘密鍵とSHA-256ハッシュ関数を使用してJWS担保入力のUTF-8表現のデジタル署名を生成します。出力はバイト配列になります。
結果のバイト配列をコード化Base64url。
2.出力はそのJWS用にエンコードJWS署名です。
次のようにJWS用のRSA、SHA-256デジタル署名が検証されます:
エンコードされたJWS署名を取り、base64urlはバイト配列にそれをデコードする。復号が失敗した場合、JWSは拒絶しなければなりません。
JWS担保入力のUTF-8表現との署名者によって使用される秘密鍵に対応する公開鍵送信ハッシュ関数としてSHA-256を使用してアルゴリズムをRSASSA-PKCS1-v1_5のを、確認します。
検証が失敗した場合、JWSは拒絶しなければなりません。
cert = '''-----BEGIN CERTIFICATE-----
MIICITCCAYqgAwIBAgIIPwTqlgFF5fUwDQYJKoZIhvcNAQEFBQAwNjE0MDIGA1UE
AxMrZmVkZXJhdGVkLXNpZ25vbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTAe
Fw0xNTAzMTcwODEzMzRaFw0xNTAzMTgyMTEzMzRaMDYxNDAyBgNVBAMTK2ZlZGVy
YXRlZC1zaWdub24uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wgZ8wDQYJKoZI
hvcNAQEBBQADgY0AMIGJAoGBAJ/GfMFyZGU04C31UFFFTIW0W5GvTjktwxhRrrdp
rtvLld8T4CPriH/RieQz2OjVyqi+ayK7/Ic/l9uoKPFBmtsh9rysrcQzexgPSvGQ
bsSsakjWBLL++f57IuFHN81AAwcPHc3rONRYXkEDZYec5OEk4V89RaP6GiWEdnj4
L3Z1AgMBAAGjODA2MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBYGA1Ud
JQEB/wQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4GBAAPTCQbEOmyCP7gd
AYHY7m48HLtdWzOVLQGoChoHkXPrm2oMi4TBT0Yky5z6UgafIbCl7wQ07cE7MsPY
7qXVjGH/9OVOmIb13GcTKymel1stsbHu5FDDMCLOaUxCbskxW5AhDPuenmpmlP0i
lfGkxCzzNF+Zehba+JdrEFjGTkE1
-----END CERTIFICATE-----'''
ca = default_backend().load_pem_x509_certificate(cert.encode('utf-8'))
public_key = ca.public_key()
pem = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.PKCS1
).decode('utf-8')
or
modulus_b64 = b'n8Z8wXJkZTTgLfVQUUVMhbRbka9OOS3DGFGut2mu28uV3xPgI-uIf9GJ5DPY6NXKqL5rIrv8hz-X26go8UGa2yH2vKytxDN7GA9K8ZBuxKxqSNYEsv75_nsi4Uc3zUADBw8dzes41FheQQNlh5zk4SThXz1Fo_oaJYR2ePgvdnU='
exponent_b64 = b'AQAB'
modulus_hex = binascii.hexlify(
base64.b64decode(modulus_b64.replace('-', '+').replace('_', '/')))
exponent_hex = binascii.hexlify(base64.b64decode(exponent_b64))
modulus = int(modulus_hex, 16)
exponent = int(exponent_hex, 16)
numbers = RSAPublicNumbers(e=exponent, n=modulus)
public_key = default_backend().load_rsa_public_numbers(numbers)
pem = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.PKCS1
).decode('utf-8')
"""
"""
openssl req -newkey rsa:2048 -nodes -sha256 -keyout 230498151c214b788dd97f22b85410a5.key
openssl rsa -in 230498151c214b788dd97f22b85410a5.key -pubout > 230498151c214b788dd97f22b85410a5.pub
jwt エンコードの仕方
priv_rsakey = load_pem_private_key(
bytes(pkey.read(), 'utf-8'),
password=None,
backend=default_backend())
jwt_message = jwt.encode(
{'some': 'payload'},
priv_rsakey,
algorithm='RS256',
headers={'kid': '230498151c214b788dd97f22b85410a5'})
jwt デコードの仕方
from jwt.api import load as jwt_load
from jwt.api import verify_signature as jwt_verify_signature
ppub = open('./.tmp/230498151c214b788dd97f22b85410a5.pub', 'r')
ppub_rsakey = load_pem_public_key(
bytes(ppub.read(), 'utf-8'), backend=default_backend())
ppub_rsakey = load_pem_public_key(
bytes(ppub.read(), 'utf-8'),
backend=default_backend())
load_output = jwt_load(jwt_message)
jwt_verify_signature(key=ppub_rsakey, *load_output)
"""
cert = """-----BEGIN CERTIFICATE-----
MIIDSjCCAjICCQCLT6DB34vBizANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJK
QTEOMAwGA1UECBMFVG9reW8xEDAOBgNVBAoTB2hhbC5pbmMxEjAQBgNVBAMTCWxv
Y2FsaG9zdDEiMCAGCSqGSIb3DQEJARYTZ3VyaW11c2FuQGdtYWlsLmNvbTAeFw0x
NTAzMTYxMjQ2NDZaFw0xNjAzMTUxMjQ2NDZaMGcxCzAJBgNVBAYTAkpBMQ4wDAYD
VQQIEwVUb2t5bzEQMA4GA1UEChMHaGFsLmluYzESMBAGA1UEAxMJbG9jYWxob3N0
MSIwIAYJKoZIhvcNAQkBFhNndXJpbXVzYW5AZ21haWwuY29tMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3950WkQWPBqdrnjsYwgyTrctSJ6LJrJvMY7h
0FZZljN2RE4AkGhGeNZw0sZzdQnk7G4UbK2T0S5lzT49PnoVlDK60sntfMqv6SKh
oGs6iGSI4nwFT9uxpOmy0w4NwI2ScWHF1QbAXSrfT7Xj+kFsMdRv6LkwgZu02uHA
GitRbh4e4R77kSWGn8ZmARWV1X4yGE3L9WAJ7GK8U31mjNCPyVmSA8CBG4x3Kdwl
pB02rqXl6sGc4uZ5D5xRBygeeHgGTdD8QFUXSLC5fRV/jJeuweGJVYLavlECvICR
R3Gz5jhmvLEHUxfG8+EITg+uNdLF9H1ghsf6BZr5I4QMvI4qfwIDAQABMA0GCSqG
SIb3DQEBBQUAA4IBAQAJshGUtLuTTB8s6DnT7C2FQZ6EiqRduEjp0X7SzmyUd0fN
D7s//HpZRNSe5Vo+cfIRXqc53jC0yuL5cVvm4hwgGoX6J7dt4BL8ZIjLWPGCWL6y
qQboc1SegBtVhDk49dC1AEPfnpX3ehfUpmANTZRMmuoly21+vNqUu55NnIKTcdq2
/0RF/NDDugZ2dNjzdY/5pq50xNocz3jXRHPtp1r4h4Qb3yhCZ9o4fOor7MDq0Cld
wZAhIngPwhaT6qgegR+ebO8yAYpVun1A4qhyyt/6RwHRqxPCBtEkZCj8kvwXQw+N
1UqGi9a6DHIhe3ZiGWCqvOlWWTwoMvjJ54jMVtAs
-----END CERTIFICATE-----"""
def generate_jwks():
ca = default_backend().load_pem_x509_certificate(cert.encode('utf-8'))
public_key = ca.public_key()
pem = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.PKCS1
).decode('utf-8')
public_rsa_numbers = public_key.public_numbers()
modulus = base64.urlsafe_b64encode(
hex(public_rsa_numbers.n).lstrip('0x').encode('utf-8'))
exponent = base64.urlsafe_b64encode(
hex(public_rsa_numbers.e).lstrip('0x').encode('utf-8'))
print('=== X.509 Cert to Public Key ===')
print('X.509 Cert :')
print(cert)
print('Public Key :')
print(pem)
print('Modulus : ')
print(modulus.decode('utf-8'))
print('Exponent : ')
print(exponent.decode('utf-8'))
print('================================')
return {
'kty': 'RSA',
'alg': 'RS256',
'use': 'sig',
'n': modulus,
'e': exponent
}
def generate_rsa_public_key_from_jwks(jwks):
modulus = int(b'0x' + base64.urlsafe_b64decode(jwks['n']), 16)
exponent = int(b'0x' + base64.urlsafe_b64decode(jwks['e']), 16)
numbers = RSAPublicNumbers(e=exponent, n=modulus)
public_key = default_backend().load_rsa_public_numbers(numbers)
pem = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.PKCS1
).decode('utf-8')
print('=== Modulus, exponent to Public Key ===')
print('Modulus : ')
print(jwks['n'])
print('Exponent : ')
print(jwks['e'])
print('Public Key : ')
print(pem)
print('================================')
return public_key
def main():
jwks = generate_jwks()
print(jwks)
generate_rsa_public_key_from_jwks(jwks)
if __name__ == '__main__':
main()
"""
from OpenSSL import crypto
pkey = crypto.PKey()
pkey.generate_key(crypto.TYPE_RSA, 2048)
req = crypto.X509Req()
req.get_subject().C = "JP"
req.get_subject().ST = "Tokyo"
req.get_subject().L = "Edogawaku"
req.get_subject().O = "hal.inc"
req.get_subject().OU = "hal.inc"
req.get_subject().CN = 'localhost'
req.set_issuer('localhost')
req.sign(pkey, 'SHA256')
crypto.dump_certificate_request(crypto.FILETYPE_PEM, req)
cert = crypto.X509()
cert.get_subject().C = "JP"
cert.get_subject().ST = "Tokyo"
cert.get_subject().L = "Edogawaku"
cert.get_subject().O = "hal.inc"
cert.get_subject().OU = "hal.inc"
cert.get_subject().CN = 'localhost'
cert.set_serial_number(1000)
cert.gmtime_adj_notBefore(0)
cert.gmtime_adj_notAfter(10*365*24*60*60)
cert.set_issuer(cert.get_subject())
cert.set_pubkey(pkey)
cert.sign(pkey, 'sha256')
crypto.dump_certificate(crypto.FILETYPE_PEM, cert)
crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
cert = '''-----BEGIN CERTIFICATE-----
MIICCzCB+AIBADANBgkqhkiG9w0BAQsFADBpMQswCQYDVQQGEwJKUDEOMAwGA1UE
CAwFVG9reW8xEjAQBgNVBAcMCUVkb2dhd2FrdTEQMA4GA1UECgwHaGFsLmluYzEQ
MA4GA1UECwwHaGFsLmluYzESMBAGA1UEAwwJbG9jYWxob3N0MAQfAB8AMGkxCzAJ
BgNVBAYTAkpQMQ4wDAYDVQQIDAVUb2t5bzESMBAGA1UEBwwJRWRvZ2F3YWt1MRAw
DgYDVQQKDAdoYWwuaW5jMRAwDgYDVQQLDAdoYWwuaW5jMRIwEAYDVQQDDAlsb2Nh
bGhvc3QwCDADBgEAAwEAMA0GCSqGSIb3DQEBCwUAA4H+AJzOZYWlRCs9Nj1KMHn4
rgINt5sJUinKc5ulFUQfMyXFhr16vH41J6hMSbaW0xX6dqOrzhiBaS2mh2pfdvdX
Ic1Z1VvbE7ZrAihxujNgsbHd77IC0xDm4YbxACJd7y4O3jxnxzOBhNsQUOG3pCdZ
K6dRl9jCmiIgBGMamfHJwMXSN4sbLO7xK1yUriTY3qu/DYrl2Ls6PWcm/dqZh2P/
qT0NiPIZfsc6hQvfKffny8KqizQXd8X8+b3oZfBuE3kLoPcHAR5XasXzylmfJAKt
IRshCtuoSB5NetUeYFcTaecjwjDtmdQuJIHzKmrcDu1Bjg2u1DiQe9Acf+MXw0g=
-----END CERTIFICATE-----'''
ca = default_backend().load_pem_x509_certificate(cert.encode('utf-8'))
public_key = ca.public_key()
pem = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.PKCS1
).decode('utf-8')
cert = '''-----BEGIN CERTIFICATE-----
MIICITCCAYqgAwIBAgIIcAilVKRkTx4wDQYJKoZIhvcNAQEFBQAwNjE0MDIGA1UE
AxMrZmVkZXJhdGVkLXNpZ25vbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTAe
Fw0xNTAxMjUyMDU4MzRaFw0xNTAxMjcwOTU4MzRaMDYxNDAyBgNVBAMTK2ZlZGVy
YXRlZC1zaWdub24uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wgZ8wDQYJKoZI
hvcNAQEBBQADgY0AMIGJAoGBALS907RRI7VSJRazLMkZ3L0umSw0a+j3o3kL+4cd
ZPqF9OffTk2AOBUBPGGF+M/efzWkF8fN9wz2suylc8O+dZByc/XokmMmZmBTDO/O
hPj7KRb3STIVNmQi4MS1F2fxquzkYMR5CR3AVkfB7LYyN86VgDoX6oPGL0pzHjkr
UNTbAgMBAAGjODA2MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBYGA1Ud
JQEB/wQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4GBAH+l4BlDBOoxAv6/
l8CI81tbEgzlQGZ/aQKDVhUC21tkUiCS3M39ZXOrK54Aav/nDPArAu7KMCvGyNrW
tIQvrf5Mi14C9Y9mk2imFPtxGjOF6haxfCGkubnFY05Two/dkUG7Qm8bzJQy5j23
/0QCIx4dSMiv0ON6GFlMAKbPglM5
-----END CERTIFICATE-----'''
cert = b'''-----BEGIN CERTIFICATE-----\nMIIDJjCCAg6gAwIBAgIICRigudMi2EAwDQYJKoZIhvcNAQEFBQAwNjE0MDIGA1UE\nAxMrZmVkZXJhdGVkLXNpZ25vbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTAe\nFw0xNTA2MzAwNTQzMzRaFw0xNTA3MDExODQzMzRaMDYxNDAyBgNVBAMTK2ZlZGVy\nYXRlZC1zaWdub24uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wggEiMA0GCSqG\nSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDLOVVK5t7uk9BeEsrIr0TUxGJFkB8cPL0G\nscsHYcGFpobgOR2z6hIwBaDgq7kWOTl/aFqAVWOXcnb2XX9s7kSP3B8uV1u05w2k\nj/juSrjzX8ik5BKLzaXpyZPPZvaHgV17d3ver/zmdMWPbmOIGXE7eWPS6KOxZhq9\nAn3QqVRyMynIIADQr0V7vMiUpo5fUeCUyMZe7ext1pC3oDpRa9iZ/k3GJcfMm7c5\naKkWAclQciF9/wKXPUqAz4UN75nJKP5kfCApdMcYTeu2789aSKORU3H+N9gsiZso\ni65uHhvO+zf+cgIOKXWYyRTXJjXkpa2a5X9+rETmMCMpfUNT8zJBAgMBAAGjODA2\nMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoGCCsG\nAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4IBAQC0KAJn8eC9wo5qRh+BB5odlXaMSc6D\nTr2yXk63SGzY0juvZ6TBgIeAvfUVi4fRurCwO+cI7O/aI3C7ZyjhPsWLfr5TfayA\npO3gxVBCt1wqxvkNiHHEY9wTQthuxdWqr05KuPFaQK2hM1iz+EOgX6AZ+5GWHtzB\nLuVRGO+ymXWOEReH8b9eR/VSSlLI8Z1bPTKsOf2xH6npOPMeYhbh1OQtxtcZJJ2q\nGdLQ5Qfu85+Db3Sjx3zVkpKUr28L/A43w9SGXyRnwPRwRbMan8MNdKcmxqAxr6jh\nX1yxy4vWNV0nS//SSJ1cKCfOtcwlgds4Fk2/bYKdG9083DxuATayGI7F\n-----END CERTIFICATE-----\n'''
cert = b'''-----BEGIN CERTIFICATE-----\nMIICnTCCAYUCAgPoMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNVBAMMCWxvY2FsaG9z\ndDAeFw0xNTA3MDExNTUzMTZaFw0yNTA2MjgxNTUzMTZaMBQxEjAQBgNVBAMMCWxv\nY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL2hszrKd8Ib\nL/cgOPOPCr4ZY/FlyXY7bJ1f/hXANKxACTFP7n2AxDoYt755JfgimlAuuzH8S97n\nxWJNlxfOB2F4Y+GYcQoXHum59u36vlh46TjMPAHDQV18lYHpWZrokJ5VjYJ30CwK\npmr/nTn2zWnUkVg+qmSOTG1VOM8runjSg3/OAujYfRs6nZMsu3SC5FxththC0h5w\nbfKO4JYB0BKNikXHZvZxnXdvwJE2ZRfOwrVxOnwY1CZkb77p2o9ReTyz39smaVTn\naFRS5PS9QZWgbQwEWZWQnzJaf/ZMNK0EG0ugftRuiQVtYQFPC5Y5D4tJGr4vV0yC\nlSpsP8ZMR+sCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAa1SpxXKQBuNqb4vwC1JR\nWyf9+JwjD2K1hQrZe1GmmL7a3j7133Kup/aE4VzSUz74Z441xSpZZXVL75hD8aZJ\n74BtXY6UTLTaujjS3R9OJwrVcxZkuFvnTxHldkCj8udQjLxv+fIPAraZFIhXfrHJ\nSyVQJdkgKXAOZ1q/adql6CvVznbaiDGrtXelfzcrCtZaKOYRVrS6TpMmvfLlX0Al\nVMXfOpoWZFBg2QJM2s2havnINoiTgl3W0t2Xlr9wBXN943jsQim8vBFAMSkcTjUS\nPC2TaEtx/4DvSBdL8gSdLrhylQRKbRq1zD1UnDas/v2E8wAW/Y9VMJ5BpY2q6uo+\n5w==\n-----END CERTIFICATE-----\n'''
b'-----BEGIN CERTIFICATE-----\nMIICnTCCAYUCAgPoMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNVBAMMCWxvY2FsaG9z\ndDAeFw0xNTA3MDExNTU1MzNaFw0yNTA2MjgxNTU1MzNaMBQxEjAQBgNVBAMMCWxv\nY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOfkIeAOg8Pv\nsloDHmipbIyYR00FhUSiv2g7by6A3X3OL8Bt5myXCBCKEaGvHGTpfcgSZ0IBSlTG\nCgUXrQgsn3w6VLKYGC6dT/tfoZxRqwN13jaxXWGlPqI238l0ZPG+yRzXvItb8m49\nQwunRyRwSGMtUVdwrTMcs61Yt7IYd8g0l3KjKFwHMF7Y2NDK7bWArFrCbNTgexKc\nCpNWfAAPpC/CT+79WSptIjHN3yiwrvZ+/hulOqs1psNUHridT18zaiQgIsYiDxPx\nRHdofp4yv1Yf6qik8XrqS55QjTnG/ynWRawmG7gtVm4jTk1bfVh11QbdKo/SaJCF\ngB5blWQ36NsCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA3zF1do6rz/XMBPplPotN\n1BWHyUZuEZKGqlydoSyokA5mQzmzCcpUGxitzb3hW6xEocFb609Gkv2CMQWCZyV2\nUso+ThS4vhKWVY4Pr5cxrzdoeg8JvHiUFw1KGQA6a6TVZ5tfEf2ANDvOorQ+NdAf\n2K7VqKAx3jApE+wdnq31kyTsrBHQlShe/d0GwlRABI0ENCpfXwpKXrzJQzf3Z6pT\nhCaHnS7kuGZ4XbesZEgLgGm6cdLVpGXwf3qFHS3net/1IKYEVI1O4CpbTuRCtFBq\n0Fn26wp8MbFtacaIM9OwaryvoQGb3NHXRxIxUwiI+GQv6ITe6bfTGDroJbgl/L29\nPQ==\n-----END CERTIFICATE-----\n'
"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment