The Digital Signature Algorithm (DSA) is a standard defined in Federal Information Processing Standard (as FIPS 186) for digital signatures, and is based on discrete logarithms. It was outlined by NIST is 1991, and proposed within the Digital Signature Standard (DSS). This was then standardized with FIPS 186 in 1994, and FIPS 186-4 in 2013. Within FIPS 186-5, it is defined that DSA should not be used for the generation of signatures, but can be used for signature verification. Although DSA has a patent (Patent 5,231,668 by David W. Kravitz, who had previously worked for the NSA), NIST published the standard as a royality-free. Initally, we created a private key of \(x\) and a prime number of \(p\) with a generator of \(g\). The public key is then [\(Y=g^x \pmod p\), \(g\), \(p\)], and the private key is \(x\).
DSA Keys (PEM, DER, PKCS1, PKCS8 and OpenSSH) |
Method
Initially, Bob creates two prime numbers (\(p\) and \(q\)) and generates a generator value of \(g\). Next, he generates his secret key (\(x\)) and then computes his public key:
\(Y=g^{x} \pmod p\)
We can generate DSA keys with:
$ ssh-keygen -t dsa -b 1024 -C "[email protected]"
and which will generate a 1,024-bit key pair. We typically store the private key in the ./ssh folder, and which contains a public key in the form:
ssh-dss AAAAB3NzaC1kc3MAAACBAINf5THvLt2R8KdCBEhfMCUWsby4/HAV0LwngUk2sC6ueMv/89XwsQcENVvI+Mdqg1sfw99zakmc7Od1ZlV/SeoF3hD9PP3D+kn2DoTwc6H6vNTd4rmYXSt7Nwxsmyi3ZV3HpetPO0MqLYZjR60o1Xf30Ni16khgDq/mi+5gA6MvAAAAFQD8m/c0flI8gpAcBEg5vXacyrBqdQAAAIBLa+1OI7v8xPxwnCjibFi2ImdXlHaaTUkk5N7gAU+Cadx79hsHNTYnAv0n0cZ7AOSbG51bTOjFlV43Dh1G5rqgHlJNXxdyJby9KjqZ0MEkWgFb38NSxxE/iPZpF+RcaVi6IQXplPyDqk8dkbuku+KKEwBY1FUuYG3fzBrwUD1pkQAAAIADbfwh7OhSE1J0WRaEk/4Usos5Oi6fhUyqr2u34Ereug9Gt4tkhePab3y31i2PQfsatpR+4VpBC6zpPgHQYpuqlqDRWJCd+Cxo9751nOiA3xYVxNoiwIn/WxoUkC8Jv8kYFAJRceXkF/auVh77MUoruAmoT2lGE6zP6ngP2q6jFw==
The private key typically has a PEM form:
-----BEGIN DSA PRIVATE KEY----- MIIBuwIBAAKBgQCDX+Ux7y7dkfCnQgRIXzAlFrG8uPxwFdC8J4FJNrAurnjL//PV 8LEHBDVbyPjHaoNbH8Pfc2pJnOzndWZVf0nqBd4Q/Tz9w/pJ9g6E8HOh+rzU3eK5 mF0rezcMbJsot2Vdx6XrTztDKi2GY0etKNV399DYtepIYA6v5ovuYAOjLwIVAPyb 9zR+UjyCkBwESDm9dpzKsGp1AoGAS2vtTiO7/MT8cJwo4mxYtiJnV5R2mk1JJOTe 4AFPgmnce/YbBzU2JwL9J9HGewDkmxudW0zoxZVeNw4dRua6oB5STV8XciW8vSo6 mdDBJFoBW9/DUscRP4j2aRfkXGlYuiEF6ZT8g6pPHZG7pLviihMAWNRVLmBt38wa 8FA9aZECgYADbfwh7OhSE1J0WRaEk/4Usos5Oi6fhUyqr2u34Ereug9Gt4tkhePa b3y31i2PQfsatpR+4VpBC6zpPgHQYpuqlqDRWJCd+Cxo9751nOiA3xYVxNoiwIn/ WxoUkC8Jv8kYFAJRceXkF/auVh77MUoruAmoT2lGE6zP6ngP2q6jFwIVAJMF5kZ+ AUZbUBUpZaPuZ15RL8GF -----END DSA PRIVATE KEY-----
In the following, we have a DSA key pair for DER format:
Private key encoding: Encoding.DER Private key format: PrivateFormat.PKCS8 Public key encoding: Encoding.DER Public key format: PublicFormat.SubjectPublicKeyInfo Curve: DSA Key size: 1024 Private key: 3082014a0201003082012b06072a8648ce3804013082011e02818100e6f762a4770e0eb6d52582707192bb80cbf51c78ae28edbbcd3807204e5b7fb87ec56c72290ac014f14b8a5142edc8ceafb5f72acd16b73ded02f4c3b6a512c8262d26fd7791828748e7ace139e5d1f218f98a0f2b3972abf46133d1b925ddbb6a50c8f31a307907e9fac3909e0d9c9950720be76cfc086353ff91e1a93ae769021500ac0f971ff1800c54ece1e60d771d85891aa4692d02818010f4fe6f8d2c6e22ca87391aebdc6d22e35a9c4723f7398de2628eb7c2237639f9bbeb16f26f218789c271528ad133b1b3f22e0c6d2a700d36c4c3d38f3e7b042883858d1b5236fd95cd2664bd53c4583145a92ff03067b21da2004a5369261b89d025183296f086d1390179d23b1f69fda97b9a9891dbcd0079106f3206ead104160214634ee4a781e089133b54c30d01bf3756f9cec7ac Public key: 308201b63082012b06072a8648ce3804013082011e02818100e6f762a4770e0eb6d52582707192bb80cbf51c78ae28edbbcd3807204e5b7fb87ec56c72290ac014f14b8a5142edc8ceafb5f72acd16b73ded02f4c3b6a512c8262d26fd7791828748e7ace139e5d1f218f98a0f2b3972abf46133d1b925ddbb6a50c8f31a307907e9fac3909e0d9c9950720be76cfc086353ff91e1a93ae769021500ac0f971ff1800c54ece1e60d771d85891aa4692d02818010f4fe6f8d2c6e22ca87391aebdc6d22e35a9c4723f7398de2628eb7c2237639f9bbeb16f26f218789c271528ad133b1b3f22e0c6d2a700d36c4c3d38f3e7b042883858d1b5236fd95cd2664bd53c4583145a92ff03067b21da2004a5369261b89d025183296f086d1390179d23b1f69fda97b9a9891dbcd0079106f3206ead1038184000281805d26332645337b3cb82982d1f708e77a28d46965a9a7cef9f452d1fa39fa7867295e06db5bfac96e103b2636e9d8538544d38c1d30b884c79c33d5132897f6ef9ab95c973affb44df9434a6071f0a47839bb435d454efcd8e6acbf4c22cbaaffb60933303bd96d6e23244dfddc3833818414e0a4c6fd4cb5d482d70a14bc5780 == Key details == Private key x: 566949463038029484803458682052869802367728404396 Public key Y: 65411605343451730957777234671995236034214926320986927255144039081006419119153114115956761402729552636033782126577976016566329716032648432797695409081341277865562415271646402872439087372081734530311944500353363321573085372207689616603347393645645585367396499832638787174002289640596290950757882636796520322944 Public key p: 162190085870034660130682717039879691549855646934095396056271866326947467300866652335833528341043951766662756032855493125230120866566862906680992805756549627396050155916924271639862014224484602858511725922579041335977233783107955239071296304137680083975744841757106537225640437115199619350222634973285410596713 Public key q: 982294088584616238961009425673231566401849026861 Public key g: 11907615530220677812166687414760608928009050454547361088172396995155182707655331896240326393508919368531467387339418834668285261114237713475098355121960991338706504398334591601017704905988816315783553419994715239294014560177819141790149672857666315463082822119241698832565275626775852028012158248595413723857
and for PEM:
Private key encoding: Encoding.PEM Private key format: PrivateFormat.TraditionalOpenSSL Public key encoding: Encoding.PEM Public key format: PublicFormat.SubjectPublicKeyInfo Curve: DSA Key size: 1024 Private key: -----BEGIN DSA PRIVATE KEY----- MIIBuwIBAAKBgQDXXKHuxa0a+Hrer26z+cgnSZgSpdh1C22ldgpczOqxMvtFMXeg lEUJmDDIMSvqug/kGxDHSKn0hJghaIpUiU9aPJtiRi4zdFiNOVmlaD3LsBK+yTDr C6iWbhABfZAZXThZaKWj/I/CL7mRo5nvyhtgOxIb9Dan6Qx6Ppa0p6EWdwIVAIlq Yt59OSNkD0Le8+bGWIEwBSKXAoGAAORfR3/hBgK5vWMHJ+sgZaz2MYRo3UjuJJ8Z Xw/PwQnBbz6D+9wnPr26yE5o4orW0Xh3DPLbLlNEQuaUmpxi9Ob1C2K/A8AFm3HU rIwV11hSNJL9u9xpfePxz7cp3PPk206S2asqb5QpfQrY+BA5iRSgv1+JCsMfTtrt q0GoBAcCgYEAuudyjGi9VbigTL3aro++/J2z7rZaetubfobWO6t5I7Oc07betTa+ iyF8pkbij2UL7W3SGvirU3KT40Ea6h/WTRG4WR28AT0U51lgX1rHIsu/7Ju/6eqa eN5P5p1cMInuVUiD5B4NceP3pFyza39P3d+Gy35ZJJ7sVe9+HGk8MfcCFHhmcOfh gxp1AljsB4FdOS8jiLl/ -----END DSA PRIVATE KEY----- Public key: -----BEGIN PUBLIC KEY----- MIIBtzCCASsGByqGSM44BAEwggEeAoGBANdcoe7FrRr4et6vbrP5yCdJmBKl2HUL baV2ClzM6rEy+0Uxd6CURQmYMMgxK+q6D+QbEMdIqfSEmCFoilSJT1o8m2JGLjN0 WI05WaVoPcuwEr7JMOsLqJZuEAF9kBldOFlopaP8j8IvuZGjme/KG2A7Ehv0Nqfp DHo+lrSnoRZ3AhUAiWpi3n05I2QPQt7z5sZYgTAFIpcCgYAA5F9Hf+EGArm9Ywcn 6yBlrPYxhGjdSO4knxlfD8/BCcFvPoP73Cc+vbrITmjiitbReHcM8tsuU0RC5pSa nGL05vULYr8DwAWbcdSsjBXXWFI0kv273Gl94/HPtync8+TbTpLZqypvlCl9Ctj4 EDmJFKC/X4kKwx9O2u2rQagEBwOBhQACgYEAuudyjGi9VbigTL3aro++/J2z7rZa etubfobWO6t5I7Oc07betTa+iyF8pkbij2UL7W3SGvirU3KT40Ea6h/WTRG4WR28 AT0U51lgX1rHIsu/7Ju/6eqaeN5P5p1cMInuVUiD5B4NceP3pFyza39P3d+Gy35Z JJ7sVe9+HGk8Mfc= -----END PUBLIC KEY----- == Key details == Private key x: 687363403990119008905968703559606616324735285631 Public key Y: 131248516556535542156049004112784484382291626712121200937340280459720200418552741655495937450498274897421747554101735953346718517825924818622952951225404755367990016708512076900475139316223348220130366921747142825246877440148885634453627404282240702549908136468256727965642470074314119412110650322212401983991 Public key p: 151232231203225881490655603441235541569568266199497909192054046567340725205956554273445670255216409833154135791921731408677525637355860454454997442668453514715893387112071278055599083417934481397472115134761190288308286639770103753461216784169497103945186547992884105474108822045205356335583220683396287108727 Public key q: 784504227307067208031380221045200701959862297239 Public key g: 626439069689578950609173624360309099652481666382682966357985428377599901038923127357698455340958645996876693342241438027837288717410163903645094041197501406508673705487306064200763701797359109016596142562311739968815407602836619750644761027337893898842803438532980370089704427217506065971706852833491420167
For an OpenSSL key we get:
Private key encoding: Encoding.PEM Private key format: PrivateFormat.PKCS8 Public key encoding: Encoding.OpenSSH Public key format: PublicFormat.OpenSSH Curve: DSA Key size: 1024 Private key: -----BEGIN PRIVATE KEY----- MIIBSgIBADCCASsGByqGSM44BAEwggEeAoGBAIWDQt90jv1OW6C6zpdjmaGg73Xq x+lNC/ZxegzTHTmzhRgj1B0j2m5nB7r5SQRDBSWzwZbqZLRTI8bfFwgjBpHuFpBK DP7X61ajGWb2gqZGPU8qXstHUlTT3wZOVVoS8kDFSOoRJ097ZzNQX/l3n4STpaFo /yd0P7ayVm5cW0TnAhUA9JeZ2ybD/5do5qHdmVmxvSKpl48CgYBSvYacj9dFVpl8 UcbajkR0JyTQmOLC/bQW4lnWudp8EeOqi5vX0mvooNCv8qUuZBPWyhlFYzgQgJ/r BHJSvP/IkaeVibnByZOzriEEwsfPRswenvapYIF5dCxU+rguvn2ZviZCuYoXmuxo rooqZWsUGKXAGHoEXQD5kjiyLT8O0AQWAhRuUAMNsTBeTbBOe2MUxWuQFqLCUw== -----END PRIVATE KEY----- Public key: ssh-dss AAAAB3NzaC1kc3MAAACBAIWDQt90jv1OW6C6zpdjmaGg73Xqx+lNC/ZxegzTHTmzhRgj1B0j2m5nB7r5SQRDBSWzwZbqZLRTI8bfFwgjBpHuFpBKDP7X61ajGWb2gqZGPU8qXstHUlTT3wZOVVoS8kDFSOoRJ097ZzNQX/l3n4STpaFo/yd0P7ayVm5cW0TnAAAAFQD0l5nbJsP/l2jmod2ZWbG9IqmXjwAAAIBSvYacj9dFVpl8UcbajkR0JyTQmOLC/bQW4lnWudp8EeOqi5vX0mvooNCv8qUuZBPWyhlFYzgQgJ/rBHJSvP/IkaeVibnByZOzriEEwsfPRswenvapYIF5dCxU+rguvn2ZviZCuYoXmuxorooqZWsUGKXAGHoEXQD5kjiyLT8O0AAAAIAPVkMwCpk5rC91eh2LxSheaYesA8wFirk5ZbdW79fIsoK/m+0URpk0fF0BTcHTvqsSaqoho2HfpVevPU8z9/sJCp63ttcOmYKqwE6UufFOGAcNhao+yWuQOmDDtmDvpknRUTfV+rTW3q7twuiCnfhSGlB7cWt3uTqkR3CxJaso1w== == Key details == Private key x: 629773310402557860974683927621963742530353939027 Public key Y: 10769981468620316763336039520233601775487089021323576253107887968207933084473887373646513301826350638925399669156553175785244391571959089167368957380180763001742261703252413699448335562066723599654006998039604874577069650205129402845058845988610380174231547907596375180915668487880097327025329658974322763991 Public key p: 93755833822232228158567108530927940635266308534182777053457260903729730036909066323303374121374680215026945715145106798227351845168427879779295892866589205755439274088916041050087512263454477237374741789590494863789086419764380958319932399265346354789670681982512774149952965421183813036599026541244291171559 Public key q: 1396374563359109228748127255314036761747442472847 Public key g: 58102239325116642494474123515227868979438485535401901064744869637362746457944065203017162202637373065224583400516991794378143944259206150994771701615207249751076667560332247055505231587086843864593613760893430481812765820452409542669884323923120237228736415344901697752350885339879075819648444515541885849296
Coding
The code we can use is:
from cryptography.hazmat.primitives import serialization as crypto_serialization from cryptography.hazmat.primitives.asymmetric import dsa from cryptography.hazmat.backends import default_backend as crypto_default_backend import binascii import sys keysize=1024 private_key_encoding= crypto_serialization.Encoding.PEM # PEM or DER public_key_encode=0 public_key_form=0 private_key_encode=0 private_key_form=0 private_key_format= crypto_serialization.PrivateFormat.PKCS8 public_key_format= crypto_serialization.PrivateFormat.TraditionalOpenSSL if (len(sys.argv)>1): keysize=int(sys.argv[1]) if (len(sys.argv)>2): private_key_encode=int(sys.argv[2]) if (len(sys.argv)>3): private_key_form=int(sys.argv[3]) if (len(sys.argv)>4): public_key_encode=int(sys.argv[4]) if (len(sys.argv)>5): public_key_form=int(sys.argv[5]) if (private_key_encode==0): private_key_encoding= crypto_serialization.Encoding.DER elif (private_key_encode==1): private_key_encoding= crypto_serialization.Encoding.PEM else: private_key_encoding= crypto_serialization.Encoding.OpenSSH if (private_key_form==0): private_key_format= crypto_serialization.PrivateFormat.PKCS8 elif (private_key_form==1): private_key_format= crypto_serialization.PrivateFormat.OpenSSH else: private_key_format= crypto_serialization.PrivateFormat.TraditionalOpenSSL if (public_key_encode==0): public_key_encoding= crypto_serialization.Encoding.DER elif (public_key_encode==1): public_key_encoding= crypto_serialization.Encoding.PEM else: public_key_encoding= crypto_serialization.Encoding.OpenSSH if (public_key_form==0): public_key_format= crypto_serialization.PublicFormat.SubjectPublicKeyInfo elif (public_key_form==1): public_key_format= crypto_serialization.PublicFormat.OpenSSH # public_key_encoding= crypto_serialization.Encoding.OpenSSH # TraditionalOpenSSL, PKCS8, Raw, OpenSSH, PKCS12 # public_key_format = crypto_serialization.PublicFormat.PKCS1 # PKCS1, OpenSSH, Raw, SubjectPublicKeyInfo key = dsa.generate_private_key( backend=crypto_default_backend(), key_size=keysize ) try: print("Private key encoding:\t",private_key_encoding) print("Private key format:\t",private_key_format) print("Public key encoding:\t",public_key_encoding) print("Public key format:\t",public_key_format) print("Curve:\t\t\tDSA") print(f"Key size:\t\t{keysize}") private_key = key.private_bytes(private_key_encoding,private_key_format,crypto_serialization.NoEncryption()) if (private_key_encoding== crypto_serialization.Encoding.DER or private_key_encoding== crypto_serialization.Encoding.Raw): print(f"\nPrivate key:\n{binascii.b2a_hex(private_key).decode()}") else: print(f"\nPrivate key:\n{private_key.decode()}") except Exception as e: print("Private key error: ",e) try: public_key = key.public_key().public_bytes(public_key_encoding,public_key_format) if (public_key_encoding== crypto_serialization.Encoding.DER or public_key_encoding== crypto_serialization.Encoding.Raw): print(f"\nPublic key:\n{binascii.b2a_hex(public_key).decode()}") else: print(f"\nPublic key:\n{public_key.decode()}") except Exception as e: print("\nPublic key error: ",e) print("\n== Key details ==") print(f"Private key x: {key.private_numbers().x}") print(f"Public key Y: {key.private_numbers().public_numbers.y}") print(f"Public key p: {key.private_numbers().public_numbers.parameter_numbers.p}") print(f"Public key q: {key.private_numbers().public_numbers.parameter_numbers.q}") print(f"Public key g: {key.private_numbers().public_numbers.parameter_numbers.g}"))