Using the Microsoft recommended procedures to create a Master Hash:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa381960%28v=vs.85%29.aspx
I have successfully developed a TLS program that works like a charm on Win Vista and Win 7. Unfortunately, it fails on Win 8.1 with the call:
CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterKey, 0, &hMasterHash);
returning an error 0x80090020.
Acquiring the context PROV_RSA_SCHANNEL provides the following info:
Provider Type Provider TypeName
------------------------------
1 RSA Full (Signature and Key Exchange)
3 DSS Signature
12 RSA SChannel
13 DSS Signature with Diffie-Hellman Key Exchange
18 Diffie-Hellman SChannel
24 RSA Full and AES
Provider Type Provider Name
------------------------------
1 Microsoft Base Cryptographic Provider v1.0
13 Microsoft Base DSS and Diffie-Hellman Cryptographic Provider
3 Microsoft Base DSS Cryptographic Provider
1 Microsoft Base Smart Card Crypto Provider
18 Microsoft DH SChannel Cryptographic Provider
1 Microsoft Enhanced Cryptographic Provider v1.0
13 Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider
24 Microsoft Enhanced RSA and AES Cryptographic Provider
12 Microsoft RSA SChannel Cryptographic Provider
1 Microsoft Strong Cryptographic Provider
Default Provider Name : Microsoft Strong Cryptographic Provider
ALGID dwBits algType namelen Name
------------------------------
26126 128 Data_Encrypt 8 AES 128
26128 256 Data_Encrypt 8 AES 256
26114 128 Data_Encrypt 4 RC2
26625 128 Data_Encrypt 4 RC4
26113 56 Data_Encrypt 4 DES
26121 112 Data_Encrypt 13 3DES TWO KEY
26115 168 Data_Encrypt 5 3DES
32772 160 Hash 6 SHA-1
32771 128 Hash 4 MD5
32776 288 Hash 12 SSL3 SHAMD5
32773 0 Hash 4 MAC
41984 1024 Exchange 9 RSA_KEYX
32777 0 Hash 5 HMAC
19461 40 Msg_Encrypt 12 SSL2 MASTER
19457 384 Msg_Encrypt 12 SSL3 MASTER
19462 384 Msg_Encrypt 12 TLS1 MASTER
19458 0 Msg_Encrypt 16 SCH MASTER HASH
19459 0 Msg_Encrypt 12 SCH MAC KEY
19463 0 Msg_Encrypt 12 SCH ENC KEY
I am using SCHANNEL_ENC_KEY = CALG_RC4/128 and SCHANNEL_MAC_KEY = CALG_SHA1/160, but CALG_AES_256/256 or CALG_3DES/168 produces the same error. Using SCHANNEL_MAC_KEY = CALG_SHA_256 fails at the preceeding CryptSetKeyParam with an error 80090005.
I posted this question to MSDN more than 2 months ago, and have yet to get a response.
Related
I'm trying to convert a module writing in Python to Perl 6, I find there is no AES method in Perl 6:
from Cryptodome.Cipher import AES
import base64
def aes(text, key):
pad = 16 - len(text) % 16
text = text + bytearray([pad] * pad)
encryptor = AES.new(key, 2, b"0102030405060708")
ciphertext = encryptor.encrypt(text)
return base64.b64encode(ciphertext)
Is there any module writing in Perl 6 that implemented AES method?
It seems that the OpenSSL module provides access to various AES ciphers. It depends on the openssl library being available (although on Windows I believe it downloads the DLL as part of the module installation process).
With that installed (zef install OpenSSL), one can:
use OpenSSL::CryptTools;
And then use encrypt/decrypt:
# Fake IV and key
my $iv = ('0' x 16).encode;
my $key = ('xy' x 16).encode;
# Encrypt.
my $ciphertext = encrypt("asdf".encode, :aes256, :$iv, :$key);
say $ciphertext;
# Decrypt.
say decrypt($ciphertext, :aes256, :$iv, :$key).decode;
See these tests for more examples.
I just need to trust a bunch public keys to use it with pass.
Unfortunately I didn't find an easy way to trust all the public keys I've stored locally.
The procees I found it its quite expensive in order of time:
> gpg --edit-key XXXXXXXXXXXXXXXX
gpg (GnuPG) 2.2.10; Copyright (C) 2018 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
pub rsa4096/XXXXXXXXXXXXXXXX
created: 2018-11-16 expires: never usage: SC
trust: unknown validity: unknown
sub rsa4096/XXXXXXXXXXXXXXXX
created: 2018-11-16 expires: never usage: E
[ unknown] (1). email#example.com
gpg> trust
pub rsa4096/XXXXXXXXXXXXXXXX
created: 2018-11-16 expires: never usage: SC
trust: unknown validity: unknown
sub rsa4096/XXXXXXXXXXXXXXXX
created: 2018-11-16 expires: never usage: E
[ unknown] (1). email#example.com
Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)
1 = I don't know or won't say
2 = I do NOT trust
3 = I trust marginally
4 = I trust fully
5 = I trust ultimately
m = back to the main menu
Your decision? y
Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y
pub rsa4096/XXXXXXXXXXXXXXXX
created: 2018-11-16 expires: never usage: SC
trust: ultimate validity: unknown
sub rsa4096/XXXXXXXXXXXXXXXX
created: 2018-11-16 expires: never usage: E
[ unknown] (1). email#example.com
Please note that the shown key validity is not necessarily correct
unless you restart the program.
gpg> q
How to do it quickly?
Looking around I found a blog that describe the process:
ow-to-ultimately-trust-a-public-key-non-interactively
The solution proposed there however doesn't work with the currect gpg version.
To make it working I used the follow commands:
gpg --list-keys --fingerprint |grep pub -A 1|egrep -Ev "pub|--"|tr -d ' ' \
| awk 'BEGIN { FS = "\n" } ; { print $1":6:" } ' | gpg --import-ownertrust
Basically it create a ownertrust text that is then imported on the fly by gpg.
I have a Certificates.p12 file that I wish to convert to a certificates.pem containing an unencrypted private key in PKCS#1 format. I have previously been able to do this by running:
openssl pkcs12 -in Certificates.p12 -out certificates.pem -nodes -clcerts
The resulting certificates.pem file has a PRIVATE KEY PEM block, as expected. However, the library I'm using does not understand this PEM block, because it expects it to be a PKCS#1 private key. The ASN.1 structure of a PKCS#1 private key is defined by RFC 3447 as:
RSAPrivateKey ::= SEQUENCE {
version Version,
modulus INTEGER, -- n
publicExponent INTEGER, -- e
privateExponent INTEGER, -- d
prime1 INTEGER, -- p
prime2 INTEGER, -- q
exponent1 INTEGER, -- d mod (p-1)
exponent2 INTEGER, -- d mod (q-1)
coefficient INTEGER, -- (inverse of q) mod p
otherPrimeInfos OtherPrimeInfos OPTIONAL
}
The bad private key block in my certificates.pem does not have this PKCS#1 structure! Instead, its ASN.1 structure looks like this:
$ openssl asn1parse -i -in badprivatekey.pem
0:d=0 hl=4 l=1212 cons: SEQUENCE
4:d=1 hl=2 l= 1 prim: INTEGER :00
7:d=1 hl=2 l= 13 cons: SEQUENCE
9:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
20:d=2 hl=2 l= 0 prim: NULL
22:d=1 hl=4 l=1190 prim: OCTET STRING [HEX DUMP]:308204A...very long hex...
What is the above format? The documentation for openssl pkcs12 only vaguely says that its output is "written in PEM format." I need a stronger guarantee that the private key PEM block is in PKCS#1 format.
The strange thing is that openssl rsa understands the strange format of the "bad" private key, and can convert it to the right PKCS#1 structure with:
openssl rsa -in badprivatekey.pem -out goodprivatekey.pem
Although openssl rsa understands the input file, the tool seems unable to tell me why, i.e. what the format of the input file is.
What is the output format of openssl pkcs12? Specifically what is the format of its private key block? How do I make openssl pkcs12 output a correct PKCS#1 private key?
Wow, that library assumes any PEM ending with PRIVATE KEY must be PKCS1?? That is horribly wrong. There are several xx PRIVATE KEY formats and only one of them is PKCS1, see below.
Meta: I think this is a dupe but I can't find it, so answering anyway.
OpenSSL supports FOUR different PEM formats for RSA private keys:
'traditional' or 'legacy' unencrypted which is the PKCS1 format you want (https://www.rfc-editor.org/rfc/rfc8017#appendix-A.1.2) with PEM type RSA PRIVATE KEY (NOT just PRIVATE KEY)
'traditional' or 'legacy' encrypted at PEM level with OpenSSL's (SSLeay's) custom scheme which uses quite poor (and unfixable) PBKDF; this has the same PEM type RSA PRIVATE KEY but added headers Proc-type and DEK-info
PKCS8 standard/generic unencrypted (https://www.rfc-editor.org/rfc/rfc5208#section-5) with PEM type PRIVATE KEY; this is a simple ASN.1 wrapper containing an identifier for the algorithm (i.e. an OID for RSA) plus an OCTET STRING containing the algorithm-dependent part which for RSA is PKCS1
PKCS8 standard/generic encrypted (https://www.rfc-editor.org/rfc/rfc5208#section-6) with PEM type ENCRYPTED PRIVATE KEY; this encrypts the PKCS8 data within the ASN.1 with an algorithm that normally defaults to at least PBKDF2-SHA1-2048 which is decent
Because PKCS8 is more flexible, and is standard (and fairly commonly used e.g. Java), and has better encryption, it is generally preferred; see the Notes section of the manpage for the PEM_read/write functions for keys and some but not all other things.
All OpenSSL functions that read a PEM private key can read any of these (given the correct password when necessary) but which they write varies depending on the function and to an extent options. As you note pkcs12 (import) (currently) writes PKCS8, but rsa (always) writes traditional/PKCS1.
Your options are:
use rsa (as you did), or in 1.1.0 pkey -traditional, to convert to traditional
use pkcs12 in a release before 1.0.0, like 0.9.8, when it wrote traditional formats (for multiple algorithms not just RSA). Of course using an obsolete and unsupported release may expose you to flaws and even vulnerabilities that were fixed in later releases.
extract the PKCS1 part out of the (unencrypted or decrypted) PKCS8. OpenSSL uses DER for keys which means the algorithm-dependent blob, which is the value of the last field in the last group, is always the contiguous last part of the data. As an example:
# note using -passin on commandline can be insecure (see the man page)
# but is used in these examples for simplicity; for real keys
# often better to omit the option and let the program prompt
$ openssl pkcs12 -in SO47599544.p12 -passin pass:sekrit -nocerts -nodes
MAC verified OK
Bag Attributes
friendlyName: mykey
localKeyID: 54 69 6D 65 20 31 35 31 32 31 37 30 38 39 39 33 33 37
Key Attributes: <No Attributes>
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCnWIGH4p1FHOP2
wtVbxuyvSHpBGd2v+7AyVHG4EJ/9WRoWN4+aGYUOGxzdTyDxk9e7DCTjuY6ciNTh
Ph74LADfQQ0B8yGkRtKer3vO1Dg7+6ErCcIGgsfrhZqpuUfod4nSU/LnHXoAAgN5
07LVvohrJMSRTA55jn356EDv31sz/dew1ThzHjYTShGbXh0/baqLxpmm4e8OixAL
YV1glHnIdr4h6wrwkJ6TtNexc3xTLwtRf9k7pJPvg+viGh7RTqhbUcGSV+dLelNe
653LbElHtAByz4Ti9e4vUKFuzxqsaWaSYGpzxF/pdthQawV/fTa9CjLGJFFrnVqc
KT3TSJ19AgMBAAECggEAOmmubRwxAVrgR9YiW3LIUzbdVbQNqcwU6LyJJVLIRcrA
TFkAiy21QAM+xBFG0oxklSncBpFSslkg1a61aLMTatpuC+wuJgWCp1lhwgRZzLY8
v6UcUOF9nzx3jB7cdsyjEwOymfG0ECSjyfaXSfzD6YJgCsedldijKIRlhlVUpIS4
YvdPPGQMXxLr9K8dkQ9o5yTQCrpey1/dNEo7lS17/uMV++dxmka5J+/dRcm2AAIc
7dk6OX9MpGKPFODUyvFjdrWPR2qK25cmVW6hrhJuaPih+1eSd78UkR7OdoHBQEbJ
5MoXSO0eTV4rhid+dX+ynwXA2OvaZbxcr7rlZXjaAQKBgQDybaKW32RHVmjKQDXC
xyTdQTMJV7JClBKeXjqJxbgKDhKFTiapn7kNVbJ594n7twuxmTxxoN35gamsbe7q
HjEesZZvb2vgLTXnqSvSXcl32CEi554VjlNP6+jZ5JBu/Gw7qObKuWBt+/gkrtCx
d09xQllZlD354RyfS3+9jzdEXQKBgQCwttL+Gw2WEm4dPQrfxbasXKQ5hNSE42j+
i0W26xv8o1lKQFip0A4YWidfI+Cvued944ZqCTvnPv6Z+JQzidHFjg6DXWgs1GK/
olsh5xO0hoxAj1azx+11ZHKSb7Kni+jSJsz40U35mWE805HFijxzzQz45unuPZGr
d8oqXIcroQKBgQCKuU32w7JgWAPy6DdbVBW2Pl70E6jADHdzBDy/JdMgfdj/Sy84
lVuRU96jiJD+50nbwPIjm4gqBJaRQv8aHVjCVaDd94Zla7mS7O1UnbJxz812ac++
SglGjJpcRTyZJfzRTt9yVg3mIe9nHlnxk3J0PyFd70Rfvv9f8BYS5OcdSQKBgBnb
xug0ITrSm5ZftlWkYuS58bYQ/+AqPtTwoFTx9nhzlr9MxyyiK03Y82XypBBSzdMY
FjUyALgH+c2iGF2qTy3vaaRDaNkWgxSzt04wuCt0fNV9pBxOpyrEdheDjMsDqCAI
WXoXdqeNkDMMaopTfiEb4kgR0i1wiP5kWwrz2zvBAoGBAPELu0IH3jtvo849KeXW
O6U1QlxdmWS6h/La1iVRHoE2U3pxAj39IDx4P6GMrgc9VLqRKLTO1Cu9giimO2jH
8iryT5VTlrrINL3M4vXAFjSN/xwVsrLaw/mAQPOKBwNlDwxcCrlxnANnYXdrhk8n
uNmZ2VH8flBFRpSbm9aisgMr
-----END PRIVATE KEY-----
$ openssl pkcs12 -in SO47599544.p12 -passin pass:sekrit -nocerts -nodes \
| sed -e 1,/-BEGIN/d -e /-END/,\$d | openssl asn1parse
MAC verified OK
0:d=0 hl=4 l=1214 cons: SEQUENCE
4:d=1 hl=2 l= 1 prim: INTEGER :00
7:d=1 hl=2 l= 13 cons: SEQUENCE
9:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
20:d=2 hl=2 l= 0 prim: NULL
22:d=1 hl=4 l=1192 prim: OCTET STRING [HEX DUMP]:308204A4[rest snipped]
[that's PKCS8 with algo-dependent part in the OCTET STRING at offset 22]
[with a tag-length header length of 4 (the hl=4)]
You can extract the PKCS1 part using asn1parse -strparse:
$ openssl pkcs12 -in SO47599544.p12 -passin pass:sekrit -nocerts -nodes \
| sed -e 1,/-BEGIN/d -e /-END/,\$d \
| openssl asn1parse -strparse 22 -out SO47599544.raw -noout
MAC verified OK
$ openssl asn1parse -in SO47599544.raw -inform der
0:d=0 hl=4 l=1188 cons: SEQUENCE
4:d=1 hl=2 l= 1 prim: INTEGER :00
7:d=1 hl=4 l= 257 prim: INTEGER :[snipped]
268:d=1 hl=2 l= 3 prim: INTEGER :010001
273:d=1 hl=4 l= 256 prim: INTEGER :[snipped]
[rest snipped -- that's your PKCS1 format but in der so convert to pem]
$ (echo -----BEGIN RSA PRIVATE KEY-----; openssl base64 -in SO47599544.raw; \
echo -----END RSA PRIVATE KEY-----) | tee SO47599544.pem
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAp1iBh+KdRRzj9sLVW8bsr0h6QRndr/uwMlRxuBCf/VkaFjeP
mhmFDhsc3U8g8ZPXuwwk47mOnIjU4T4e+CwA30ENAfMhpEbSnq97ztQ4O/uhKwnC
BoLH64WaqblH6HeJ0lPy5x16AAIDedOy1b6IayTEkUwOeY59+ehA799bM/3XsNU4
cx42E0oRm14dP22qi8aZpuHvDosQC2FdYJR5yHa+IesK8JCek7TXsXN8Uy8LUX/Z
O6ST74Pr4hoe0U6oW1HBklfnS3pTXuudy2xJR7QAcs+E4vXuL1Chbs8arGlmkmBq
c8Rf6XbYUGsFf302vQoyxiRRa51anCk900idfQIDAQABAoIBADpprm0cMQFa4EfW
IltyyFM23VW0DanMFOi8iSVSyEXKwExZAIsttUADPsQRRtKMZJUp3AaRUrJZINWu
tWizE2rabgvsLiYFgqdZYcIEWcy2PL+lHFDhfZ88d4we3HbMoxMDspnxtBAko8n2
l0n8w+mCYArHnZXYoyiEZYZVVKSEuGL3TzxkDF8S6/SvHZEPaOck0Aq6Xstf3TRK
O5Ute/7jFfvncZpGuSfv3UXJtgACHO3ZOjl/TKRijxTg1MrxY3a1j0dqituXJlVu
oa4Sbmj4oftXkne/FJEeznaBwUBGyeTKF0jtHk1eK4YnfnV/sp8FwNjr2mW8XK+6
5WV42gECgYEA8m2ilt9kR1ZoykA1wsck3UEzCVeyQpQSnl46icW4Cg4ShU4mqZ+5
DVWyefeJ+7cLsZk8caDd+YGprG3u6h4xHrGWb29r4C0156kr0l3Jd9ghIueeFY5T
T+vo2eSQbvxsO6jmyrlgbfv4JK7QsXdPcUJZWZQ9+eEcn0t/vY83RF0CgYEAsLbS
/hsNlhJuHT0K38W2rFykOYTUhONo/otFtusb/KNZSkBYqdAOGFonXyPgr7nnfeOG
agk75z7+mfiUM4nRxY4Og11oLNRiv6JbIecTtIaMQI9Ws8ftdWRykm+yp4vo0ibM
+NFN+ZlhPNORxYo8c80M+Obp7j2Rq3fKKlyHK6ECgYEAirlN9sOyYFgD8ug3W1QV
tj5e9BOowAx3cwQ8vyXTIH3Y/0svOJVbkVPeo4iQ/udJ28DyI5uIKgSWkUL/Gh1Y
wlWg3feGZWu5kuztVJ2ycc/NdmnPvkoJRoyaXEU8mSX80U7fclYN5iHvZx5Z8ZNy
dD8hXe9EX77/X/AWEuTnHUkCgYAZ28boNCE60puWX7ZVpGLkufG2EP/gKj7U8KBU
8fZ4c5a/TMcsoitN2PNl8qQQUs3TGBY1MgC4B/nNohhdqk8t72mkQ2jZFoMUs7dO
MLgrdHzVfaQcTqcqxHYXg4zLA6ggCFl6F3anjZAzDGqKU34hG+JIEdItcIj+ZFsK
89s7wQKBgQDxC7tCB947b6POPSnl1julNUJcXZlkuofy2tYlUR6BNlN6cQI9/SA8
eD+hjK4HPVS6kSi0ztQrvYIopjtox/Iq8k+VU5a6yDS9zOL1wBY0jf8cFbKy2sP5
gEDzigcDZQ8MXAq5cZwDZ2F3a4ZPJ7jZmdlR/H5QRUaUm5vWorIDKw==
-----END RSA PRIVATE KEY-----
Or you can convert the PKCS8 body to binary and just discard the first 22+4=26 bytes (since header len hl=4 from first asn1parse above):
$ openssl pkcs12 -in SO47599544.p12 -passin pass:sekrit -nocerts -nodes \
| sed -e 1,/-BEGIN/d -e /-END/,\$d \
| openssl base64 -d | dd bs=1 skip=26 >SO47599544.raw
MAC verified OK
1192+0 records in
1192+0 records out
1192 bytes (1.2 kB) copied, 0.00892462 s, 134 kB/s
[then convert to PEM with echo BEGIN;base64(encode);echo END as above]
PS: If it's important to only read the PKCS12 once, for example to avoid retyping the password, you can use awk like
openssl pkcs12 -in file.p12 | \
awk '/BEGIN PRIVATE/,/END PRIVATE/{t=t $0 RS;next}1; \
END{process t as the whole PRIVATE KEY PEM}'
or
openssl pkcs12 -in file.p12 | \
awk '/BEGIN PRIVATE/{f=1;next}/END PRIVATE/{f=0;next}f{t=t $0 RS;next}1; \
END{process t as just the base64 body}'
What's the size of the ICMP packet payload when the type is 11, i.e. time exceeded?
Since it contains an IP header and the first 8 Bytes of the IP packet payload generating the ICMP message, I thought its size was 20 + 8 = 28.
I'm replaying some common user traffic with TTL=1. In the ICMP messages I have dumped I noticed that:
all ICMP packets generated by UDP packets have payload of size 28 Bytes
all those generated by TCP packets have payload of size 40 Bytes
Since I need to match ICMP time-exceeded messages with the packets that triggered them by comparing those bytes, this piece of information is essential, but I can't find figure out why this happens.
The problem is that you're quoting the 8-byte header payload from RFC 792, Page 4, but the requirements were changed by RFC 1812...
Time Exceeded Message (in RFC 792)
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| unused |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Internet Header + 64 bits of Original Data Datagram |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
RFC 1812, Section 4.3.2.3 dramatically increases the allowable payload in an ICMP Error message (emphasis mine):
4.3.2.3 Original Message Header
Historically, every ICMP error message has included the Internet
header and at least the first 8 data bytes of the datagram that
triggered the error. This is no longer adequate, due to the use of
IP-in-IP tunneling and other technologies. Therefore, the ICMP
datagram SHOULD contain as much of the original datagram as possible
without the length of the ICMP datagram exceeding 576 bytes. The
returned IP header (and user data) MUST be identical to that which
was received, except that the router is not required to undo any
modifications to the IP header that are normally performed in
forwarding that were performed before the error was detected (e.g.,
decrementing the TTL, or updating options).
The ICMP Errors you're generating from Scapy packets should contain all the information from the IP and TCP layers of the original packet.
As you noted, the ICMP payload is the IP header plus 8 octets of the original packet's payload. IP headers, however, are not always 20 octets long; 20 is only the minimum. The IP header itself may contain options, and the header length is indicated by the value in the IHL field of the header. See sec 3.1 of RFC 791. So it looks like the TCP packets have 12 additional octets of options in their IP headers. RFC 791 defines some standard options such as source routing and timestamping. You'll have to decode the header to determine what options are being used.
I would like to add for future reference that not only do ICMP payloads vary in size as Mike said, they might also be longer than 128 Bytes in the case of ICMP extensions for MPLS. See this draft for more information
Why is RSA keys in GnuPG limited to 4096 bits?
Would it be illegal for me to modify the source to increase the max size?
ssh-keygen does not have this limitation (e.g., I can create a key that's 32768 bits long). Why is that?
At keylength.com there is this:-
To protect a 256-bit symmetric key (e.g. AES-256), you may consider using at the minimum a 17120-bit asymmetric system (e.g. RSA).
The 4096 bit limit can be raised as described in a short article entitled "Generate large keys with GnuPG", reproduced below. This was done for the gnupg package in homebrew to allow for 8192 bit keys: PR 4201. A word of caution about memory allocation for the larger keys: comp.security.pgp.tech.
Generate large keys with GnuPG | David Norman
If you'd like to generate larger keys than 4096 bits with GnuPG, you can compile
a new version that increases the upper limit of 4096. You'll probably find
yourself generating it as RSA. Download the patch to your un-tared gnupg-1.4.19
directory and apply it with:
usbdrive#sandisk-extreme64:~/gnupg-1.4.19$ patch -p0 < gnupg_1.4.19_large_keygen.patch
patching file g10/keygen.c
usbdrive#sandisk-extreme64:~/gnupg-1.4.19$ ./configure --enable-large-secmem
[...]
checking whether to allocate extra secure memory... yes
[...]
usbdrive#sandisk-extreme64:~/gnupg-1.4.19$ make -j2
usbdrive#sandisk-extreme64:~/gnupg-1.4.19$ make check
usbdrive#sandisk-extreme64:~/gnupg-1.4.19$ sudo make install
usbdrive#sandisk-extreme64:~/gnupg-1.4.19$ gpg --gen-key --enable-large-rsa
Without the --enable-large-rsa flag, the key generation process will
automatically downgrade the key to 4096.
To compile on a Mac, you'll need to download Xcode from the App Store first. The
patch increases the upper limit of the key size to 15489 bits. Without
increasing the secure memory limit, generating a key larger than about 7680-bits
will fail because it won't be able to allocate enough memory to the process.
Generating keys larger than around 7680-bits (192-bit symmetric equivalent) can
also make it impossible to decrypt messages with standard secure memory limits
set at compile time because the gpg binary won't be able to allocate enough
secure memory to decrypt the message, even small ones.
gnupg_1.4.19_xlarge_key_gen.patch
--- g10/keygen.c 2015-02-26 12:24:21.000000000 -0500
+++ g10/keygen.c 2015-03-02 22:12:09.028419377 -0500
## -1041,8 +1041,9 ##
nbits = 2048;
log_info(_("keysize invalid; using %u bits\n"), nbits );
}
- else if (nbits > 4096) {
- nbits = 4096;
+ else if (nbits > 15489) {
+ /* fallback to RFC3766 256-bit symmetric equivalency */
+ nbits = 15489;
log_info(_("keysize invalid; using %u bits\n"), nbits );
}
## -1251,7 +1252,8 ##
PKT_public_key *pk;
MPI skey[6];
MPI *factors;
- const unsigned maxsize = (opt.flags.large_rsa ? 8192 : 4096);
+ /* New large key limit RFC3766 256-bit symmetric equivalency */
+ const unsigned maxsize = (opt.flags.large_rsa ? 15489 : 4096);
assert( is_RSA(algo) );
## -1578,7 +1580,7 ##
static unsigned int
ask_keysize (int algo, unsigned int primary_keysize)
{
- unsigned nbits, min, def=2048, max=4096;
+ unsigned nbits, min, def=2048, max=15489;
int for_subkey = !!primary_keysize;
int autocomp = 0;
gnupg_1.4.19_xlarge_secmem.patch
--- configure 2015-02-27 03:37:52.000000000 -0500
+++ configure 2015-03-02 22:28:31.488401783 -0500
## -5076,7 +5076,7 ##
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $large_secmem" >&5
$as_echo "$large_secmem" >&6; }
if test "$large_secmem" = yes ; then
- SECMEM_BUFFER_SIZE=65536
+ SECMEM_BUFFER_SIZE=131072
else
SECMEM_BUFFER_SIZE=32768
fi
Article ends. Retrieved on 2016-02-26 from an archived copy of the original.
There is pretty sensible explanation (for similar question) by Fire Ant at Security Forums:
http://www.security-forums.com/viewtopic.php?p=317962#317962
All rights reserved there, but fair use citation of short excerpt shouldn't be inappropriate methinks:
Key sizes over 4096 are not currently supported in GPG. The reason for this is that 8192 keys are very slow. If you require a key greater than 4096-bit then you should really thing about what you are using that key for?
Why does it not support anything larger? Perhaps at the time of development of GnuPG (and the continued development of RSA for that matter) and the key sizes, computing limits at the time,both for the client side use cases and the potential of government agencies being able to break a 4096 key, developers and cryptographers felt a 4096 key was large enough. Really, 4096 is a really large key and would take a very long time to break with current technology. If a government agency was after you and really wanted to get your messages they would (in the US) get a court order to put a rootkit on your machines to not even worry about breaking encryption.
Now, I haven't looked at the source code specifically, but if you change the key size to anything larger than 4096, you might have problems with other users using your key if their software doesn't support a larger key size. For example, I have a 4096 key, a friend of mine cannot send me messages from an Android device because he cannot find an application that supports anything larger than 3072! Keep that in mind.
If you want to modify the source code, you can do so easily on Debian Linux with this script:
Raising GnuPG key size limits and making ideal .conf files.
Here is a link to a bash script that increases the GnuPG key size limit beyond 4096 bits. The page also provides an ideal GnuPG .conf file.
https://gist.github.com/anonymous/3d928a0bcbb3ed92c454
Please provide input and recommended changes.