Estou brincando com o RSA para aprender e compreender.
recebi o seguinte arquivo PEM do navegador (BASE 64)
-----BEGIN CERTIFICATE-----
MIIE/jCCA+agAwIBAgISBGzkPWVoI1CDdChcRxp7jO1hMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
EwJSMzAeFw0yNDAyMTAwMzQ2MjFaFw0yNDA1MTAwMzQ2MjBaMBkxFzAVBgNVBAMT
Dmh0dHBzLWd1aWRlLmRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
p7jmFSTUYpTTIN/Qvvh9/cXNTvPY5+3sCLfxn+2DMQs+wi+tGX31n5Wk3G0GRg9q
XQ9awYaeIEjYWDpLHzwlWB5PNk1FhzO3ZYPgBDrQAqBI1TSPhQNmIm8WA5V5juQl
yEGI9efqZOuFm+1oIqFFbNtQ4ty/Vg6+FuJJx6KaRUmhQ6hpypuW4cz81ytVVJ0i
6E4rDE+jcQEHoRPxQ9K8/WkjCCuzUEdklGy9t+Jv4fUjlI2AKvhVOJKzBO8UjhTV
+tjCBR/PTmWq5Xi5NXmKx34/sgHNqx86DQ9xDiAv3X8jOiHK5eH5PhV1xKmp9BGq
OaQwG8JSDHsdt2qgy2xlnQIDAQABo4ICJTCCAiEwDgYDVR0PAQH/BAQDAgWgMB0G
A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1Ud
DgQWBBRD3wUGbTVubIcA7UYVRBcRVP9XcDAfBgNVHSMEGDAWgBQULrMXt1hWy65Q
CUDmH6+dixTCxjBVBggrBgEFBQcBAQRJMEcwIQYIKwYBBQUHMAGGFWh0dHA6Ly9y
My5vLmxlbmNyLm9yZzAiBggrBgEFBQcwAoYWaHR0cDovL3IzLmkubGVuY3Iub3Jn
LzAtBgNVHREEJjAkgg5odHRwcy1ndWlkZS5kZYISd3d3Lmh0dHBzLWd1aWRlLmRl
MBMGA1UdIAQMMAowCAYGZ4EMAQIBMIIBBQYKKwYBBAHWeQIEAgSB9gSB8wDxAHcA
SLDja9qmRzQP5WoC+p0w6xxSActW3SyB2bu/qznYhHMAAAGNkVaAmwAABAMASDBG
AiEA+YNF9WpuxNwggP9a0qHI1TXZK6ykYazxSMZDgJAqV34CIQDl05SPwsN+uDBg
PKBbu3RtPCuzXVRvSDMvggQd/lUoyAB2AKLiv9Ye3i8vB6DWTm03p9xlQ7DGtS6i
2reK+Jpt9RfYAAABjZFWgQkAAAQDAEcwRQIhANkJGz5gIcPrQEMerOTz+Y/X7KLG
JIaHP5jKiJd+OIxYAiAB+KbOm64IxyM+T8Kyr4SRimc05QEiHEaUw1zuUud8dTAN
BgkqhkiG9w0BAQsFAAOCAQEAAhTC1jNPx0WEW65qYjotHJPUsGN/PxwdQnloPcPn
gI5sq/H1jCwxaaw2DpOdD8fwAfYKMdtgQG2oKTeIRjn/AvpdYUab7S1WkC61LpGw
6lEZH2dp8Krcy0xL8BcCUR+ET2x+Zb3UKjkafZNW9XCQuRi8f6tlpJ5BpEhcJCQ6
2eU5Y10BnBZk+KiSV1rocAUtVM3Gy1m0MB6tBXayCXhOoHBmOjw/z591+k8ahOzA
DNxW3uX9Tfak/15XRKRp+Je5YpKV/8ww+LX4tO4vCK72RaD4QSsb2LRORH6BoLZA
lDPil4lBDrB40ojuGV8KaMmq88Sf2bCSTYX1pt/5bOtOyw==
-----END CERTIFICATE-----
Subject Name
CN (Common Name): https-guide.de
Issuer Name
C (Country): US
O (Organization): Let's Encrypt
CN (Common Name): R3
Issued Certificate
Version: 3
Serial Number: 04 6C E4 3D 65 68 23 50 83 74 28 5C 47 1A 7B 8C ED 61
Not Valid Before: 2024-02-10
Not Valid After: 2024-05-10
Certificate Fingerprints
SHA1: 0D 0D 1A 18 7D 9A 59 8E 40 5C 71 3B CF 46 14 E3 6B 5E B5 05
MD5: 9A AC AA 7E 7D 51 22 0E F0 DB 89 C8 67 A4 67 DF
Public Key Info
Key Algorithm: RSA
Key Parameters: 05 00
Key Size: 2048
Key SHA1 Fingerprint: 29 A8 72 98 2E 6E 88 D0 F8 AB 0C C7 65 D4 56 95 94 2E F9 2E
Public Key: 30 82 01 0A 02 82 01 01 00 A7 B8 E6 15 24 D4 62 94 D3 20 DF D0 BE F8 7D FD C5 CD 4E F3 D8 E7 ED EC 08 B7 F1 9F ED 83 31 0B 3E C2 2F AD 19 7D F5 9F 95 A4 DC 6D 06 46 0F 6A 5D 0F 5A C1 86 9E 20 48 D8 58 3A 4B 1F 3C 25 58 1E 4F 36 4D 45 87 33 B7 65 83 E0 04 3A D0 02 A0 48 D5 34 8F 85 03 66 22 6F 16 03 95 79 8E E4 25 C8 41 88 F5 E7 EA 64 EB 85 9B ED 68 22 A1 45 6C DB 50 E2 DC BF 56 0E BE 16 E2 49 C7 A2 9A 45 49 A1 43 A8 69 CA 9B 96 E1 CC FC D7 2B 55 54 9D 22 E8 4E 2B 0C 4F A3 71 01 07 A1 13 F1 43 D2 BC FD 69 23 08 2B B3 50 47 64 94 6C BD B7 E2 6F E1 F5 23 94 8D 80 2A F8 55 38 92 B3 04 EF 14 8E 14 D5 FA D8 C2 05 1F CF 4E 65 AA E5 78 B9 35 79 8A C7 7E 3F B2 01 CD AB 1F 3A 0D 0F 71 0E 20 2F DD 7F 23 3A 21 CA E5 E1 F9 3E 15 75 C4 A9 A9 F4 11 AA 39 A4 30 1B C2 52 0C 7B 1D B7 6A A0 CB 6C 65 9D 02 03 01 00 01
Key Usage
Usages: Digital signature
Key encipherment
Critical: Yes
Extended Key Usage
Allowed Purposes: Server Authentication
Client Authentication
Critical: No
Basic Constraints
Certificate Authority: No
Max Path Length: Unlimited
Critical: Yes
Subject Key Identifier
Key Identifier: 43 DF 05 06 6D 35 6E 6C 87 00 ED 46 15 44 17 11 54 FF 57 70
Critical: No
Extension
Identifier: 2.5.29.35
Value: 30 16 80 14 14 2E B3 17 B7 58 56 CB AE 50 09 40 E6 1F AF 9D 8B 14 C2 C6
Critical: No
Extension
Identifier: 1.3.6.1.5.5.7.1.1
Value: 30 47 30 21 06 08 2B 06 01 05 05 07 30 01 86 15 68 74 74 70 3A 2F 2F 72 33 2E 6F 2E 6C 65 6E 63 72 2E 6F 72 67 30 22 06 08 2B 06 01 05 05 07 30 02 86 16 68 74 74 70 3A 2F 2F 72 33 2E 69 2E 6C 65 6E 63 72 2E 6F 72 67 2F
Critical: No
Subject Alternative Names
DNS: https-guide.de
DNS: www.https-guide.de
Critical: No
Extension
Identifier: 2.5.29.32
Value: 30 0A 30 08 06 06 67 81 0C 01 02 01
Critical: No
Extension
Identifier: 1.3.6.1.4.1.11129.2.4.2
Value: 04 81 F3 00 F1 00 77 00 48 B0 E3 6B DA A6 47 34 0F E5 6A 02 FA 9D 30 EB 1C 52 01 CB 56 DD 2C 81 D9 BB BF AB 39 D8 84 73 00 00 01 8D 91 56 80 9B 00 00 04 03 00 48 30 46 02 21 00 F9 83 45 F5 6A 6E C4 DC 20 80 FF 5A D2 A1 C8 D5 35 D9 2B AC A4 61 AC F1 48 C6 43 80 90 2A 57 7E 02 21 00 E5 D3 94 8F C2 C3 7E B8 30 60 3C A0 5B BB 74 6D 3C 2B B3 5D 54 6F 48 33 2F 82 04 1D FE 55 28 C8 00 76 00 A2 E2 BF D6 1E DE 2F 2F 07 A0 D6 4E 6D 37 A7 DC 65 43 B0 C6 B5 2E A2 DA B7 8A F8 9A 6D F5 17 D8 00 00 01 8D 91 56 81 09 00 00 04 03 00 47 30 45 02 21 00 D9 09 1B 3E 60 21 C3 EB 40 43 1E AC E4 F3 F9 8F D7 EC A2 C6 24 86 87 3F 98 CA 88 97 7E 38 8C 58 02 20 01 F8 A6 CE 9B AE 08 C7 23 3E 4F C2 B2 AF 84 91 8A 67 34 E5 01 22 1C 46 94 C3 5C EE 52 E7 7C 75
Critical: No
Signature
Signature Algorithm: 1.2.840.113549.1.1.11
Signature Parameters: 05 00
Signature: 02 14 C2 D6 33 4F C7 45 84 5B AE 6A 62 3A 2D 1C 93 D4 B0 63 7F 3F 1C 1D 42 79 68 3D C3 E7 80 8E 6C AB F1 F5 8C 2C 31 69 AC 36 0E 93 9D 0F C7 F0 01 F6 0A 31 DB 60 40 6D A8 29 37 88 46 39 FF 02 FA 5D 61 46 9B ED 2D 56 90 2E B5 2E 91 B0 EA 51 19 1F 67 69 F0 AA DC CB 4C 4B F0 17 02 51 1F 84 4F 6C 7E 65 BD D4 2A 39 1A 7D 93 56 F5 70 90 B9 18 BC 7F AB 65 A4 9E 41 A4 48 5C 24 24 3A D9 E5 39 63 5D 01 9C 16 64 F8 A8 92 57 5A E8 70 05 2D 54 CD C6 CB 59 B4 30 1E AD 05 76 B2 09 78 4E A0 70 66 3A 3C 3F CF 9F 75 FA 4F 1A 84 EC C0 0C DC 56 DE E5 FD 4D F6 A4 FF 5E 57 44 A4 69 F8 97 B9 62 92 95 FF CC 30 F8 B5 F8 B4 EE 2F 08 AE F6 45 A0 F8 41 2B 1B D8 B4 4E 44 7E 81 A0 B6 40 94 33 E2 97 89 41 0E B0 78 D2 88 EE 19 5F 0A 68 C9 AA F3 C4 9F D9 B0 92 4D 85 F5 A6 DF F9 6C EB 4E CB
1) Como posso verificar a assinatura manualmente?
eu sei que o emissor é "Let's Encrypt",
obtive a chave pública do Let's Encrypt da cadeia de arquivos PEM
#PUBLIC KEY
exponent: 65537
modulo: BB:02:15:28:CC:F6:A0:94:D3:0F:12:EC:8D:55:92:C3:F8:82:F1:99:A6:7A:42:88:A7:5D:26:AA:B5:2B:B9:C5:4C:B1:AF:8E:6B:F9:75:C8:A3:D7:0F:47:94:14:55:35:57:8C:9E:A8:A2:39:19:F5:82:3C:42:A9:4E:6E:F5:3B:C3:2E:DB:8D:C0:B0:5C:F3:59:38:E7:ED:CF:69:F0:5A:0B:1B:BE:C0:94:24:25:87:FA:37:71:B3:13:E7:1C:AC:E1:9B:EF:DB:E4:3B:45:52:45:96:A9:C1:53:CE:34:C8:52:EE:B5:AE:ED:8F:DE:60:70:E2:A5:54:AB:B6:6D:0E:97:A5:40:34:6B:2B:D3:BC:66:EB:66:34:7C:FA:6B:8B:8F:57:29:99:F8:30:17:5D:BA:72:6F:FB:81:C5:AD:D2:86:58:3D:17:C7:E7:09:BB:F1:2B:F7:86:DC:C1:DA:71:5D:D4:46:E3:CC:AD:25:C1:88:BC:60:67:75:66:B3:F1:18:F7:A2:5C:E6:53:FF:3A:88:B6:47:A5:FF:13:18:EA:98:09:77:3F:9D:53:F9:CF:01:E5:F5:A6:70:17:14:AF:63:A4:FF:99:B3:93:9D:DC:53:A7:06:FE:48:85:1D:A1:69:AE:25:75:BB:13:CC:52:03:F5:ED:51:A1:8B:DB:15
tentei verificar a assinatura manualmente com um pequeno Javascript do console do navegador
var modulo="BB:02:15:28:CC:F6:A0:94:D3:0F:12:EC:8D:55:92:C3:F8:82:F1:99:A6:7A:42:88:A7:5D:26:AA:B5:2B:B9:C5:4C:B1:AF:8E:6B:F9:75:C8:A3:D7:0F:47:94:14:55:35:57:8C:9E:A8:A2:39:19:F5:82:3C:42:A9:4E:6E:F5:3B:C3:2E:DB:8D:C0:B0:5C:F3:59:38:E7:ED:CF:69:F0:5A:0B:1B:BE:C0:94:24:25:87:FA:37:71:B3:13:E7:1C:AC:E1:9B:EF:DB:E4:3B:45:52:45:96:A9:C1:53:CE:34:C8:52:EE:B5:AE:ED:8F:DE:60:70:E2:A5:54:AB:B6:6D:0E:97:A5:40:34:6B:2B:D3:BC:66:EB:66:34:7C:FA:6B:8B:8F:57:29:99:F8:30:17:5D:BA:72:6F:FB:81:C5:AD:D2:86:58:3D:17:C7:E7:09:BB:F1:2B:F7:86:DC:C1:DA:71:5D:D4:46:E3:CC:AD:25:C1:88:BC:60:67:75:66:B3:F1:18:F7:A2:5C:E6:53:FF:3A:88:B6:47:A5:FF:13:18:EA:98:09:77:3F:9D:53:F9:CF:01:E5:F5:A6:70:17:14:AF:63:A4:FF:99:B3:93:9D:DC:53:A7:06:FE:48:85:1D:A1:69:AE:25:75:BB:13:CC:52:03:F5:ED:51:A1:8B:DB:15",
signature="02 14 C2 D6 33 4F C7 45 84 5B AE 6A 62 3A 2D 1C 93 D4 B0 63 7F 3F 1C 1D 42 79 68 3D C3 E7 80 8E 6C AB F1 F5 8C 2C 31 69 AC 36 0E 93 9D 0F C7 F0 01 F6 0A 31 DB 60 40 6D A8 29 37 88 46 39 FF 02 FA 5D 61 46 9B ED 2D 56 90 2E B5 2E 91 B0 EA 51 19 1F 67 69 F0 AA DC CB 4C 4B F0 17 02 51 1F 84 4F 6C 7E 65 BD D4 2A 39 1A 7D 93 56 F5 70 90 B9 18 BC 7F AB 65 A4 9E 41 A4 48 5C 24 24 3A D9 E5 39 63 5D 01 9C 16 64 F8 A8 92 57 5A E8 70 05 2D 54 CD C6 CB 59 B4 30 1E AD 05 76 B2 09 78 4E A0 70 66 3A 3C 3F CF 9F 75 FA 4F 1A 84 EC C0 0C DC 56 DE E5 FD 4D F6 A4 FF 5E 57 44 A4 69 F8 97 B9 62 92 95 FF CC 30 F8 B5 F8 B4 EE 2F 08 AE F6 45 A0 F8 41 2B 1B D8 B4 4E 44 7E 81 A0 B6 40 94 33 E2 97 89 41 0E B0 78 D2 88 EE 19 5F 0A 68 C9 AA F3 C4 9F D9 B0 92 4D 85 F5 A6 DF F9 6C EB 4E CB",
signature_decrypt;
modulo=BigInt("0x"+modulo.replace(new RegExp(":","g"),""));
signature=BigInt("0x"+signature.replace(new RegExp(" ","g"),""));
signature_decrypt=signature;
for (let i=0;i<16;i++) //-- exponent: 65537 -> 2**16=65536
{
signature_decrypt=signature_decrypt**2n % modulo
}
signature_decrypt=signature_decrypt*signature % modulo //65537
console.log (signature_decrypt.toString(16));
obtive a seguinte saída:
1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d060960864801650304020105000420bc56117d619d50579b700bd9e3fd275a2009234dbf413c89e13c0d12664188ff
Por causa do preenchimento que obtive, acho que esta é a assinatura descriptografada correta, mas não sei de qual parte do arquivo pem devo construir o valor hash sha256, porque não obtive igualdade - ou minha descriptografia está errada.
O arquivo pem completo inclui a assinatura, então acho que o valor sha256 deveria ser feito na parte anterior, mas onde exatamente. alguém pode ajudar?
2ª pergunta : existem dois carimbos de data/hora do certificado dentro do pem SHA256
48:B0:E3:6B:DA:A6:47:34:0F:E5:6A:02:FA:9D:30:EB:1C:52:01:CB:56:DD:2C:81:D9:BB:BF:AB:39:D8:84:73
A2:E2:BF:D6:1E:DE:2F:2F:07:A0:D6:4E:6D:37:A7:DC:65:43:B0:C6:B5:2E:A2:DA:B7:8A:F8:9A:6D:F5:17:D8
quem fez isso e do que se trata, por que dois? - alguém pode vincular uma página, onde um arquivo pem é explicado linha por linha, porque eu procurei por ele e geralmente só obtive bla, bla, bla
Você acertou basicamente, mas precisa ser preciso.
Primeiro, o formato PEM é apenas um wrapper - ele representa alguns dados binários como linhas traço-BEGIN e traço-END envolvendo a codificação base64 com alfabeto A-Za-z0-9+/ preenchimento = e quebras de linha. Veja uma boa breve descrição ou o padrão atual .
Para um certificado no formato PEM , os dados binários são a codificação ASN.1 DER de uma SEQUÊNCIA de 3 elementos :
a parte 'a ser assinada' (TBS), também chamada de órgão de certificação ou 'info', em si uma subSEQUÊNCIA bastante complicada;
um 'AlgorithmIdentifier' que identifica o algoritmo de assinatura (e é redundantemente duplicado dentro do corpo), uma SEQUÊNCIA que começa com um IDENTIFICADOR DE OBJETO; e
uma BIT STRING contendo o valor da assinatura.
Assim, os dados do certificado, obtidos pela decodificação em base64 do corpo PEM, consistem em um cabeçalho para a SEQUÊNCIA externa; o TBS codificado; o AlgorithmIdentifier codificado; e o BIT STRING codificado. Todos eles têm comprimento variável, então em geral você deve olhar as codificações para descobrir onde cada uma começa e termina. A assinatura é calculada no item 1 (o TBS) e, para o seu certificado de exemplo, ela começa no deslocamento de byte 4 e tem comprimento de 1.002 bytes.
Vindo da outra direção, a assinatura RSA-PKCS1-v1_5 recupera (por modexp e) um 'representante' que consiste em
um byte 01, quantos bytes FF caberem, dado o tamanho da chave = tamanho do módulo, e um byte 00
a codificação DER de uma SEQUÊNCIA DigestInfo contendo um AlgorithmIdentifier (semelhante ao do nível externo, mas aqui apenas para o hash, não para a assinatura completa) mais uma OCTET STRING contendo os bytes de hash reais.
Seu valor recuperado menos o preenchimento 01 FF... 00 é
que decodifica como
e com certeza se eu pegar os bytes começando em 4 para 1002 de seus dados e calcular SHA256, recebo esse hash.
Observe que a estrutura DigestInfo é simples o suficiente para que também possa ser expressa apenas como um prefixo, dependendo apenas do algoritmo de hash adicionado e removido do valor de hash, conforme mostrado na próxima página do link RFC8017 que forneci.
Esses não são carimbos de data e hora como tal. Veja a decodificação mais informativa usando
openssl x509 -text
:Eles são os logids de dois SCTs. SCT é Signed Certificate Timestamp e é uma estrutura que contém um carimbo de data e hora e uma assinatura, gerada por um operador de log que enviou as informações do certificado - geralmente e neste caso um chamado 'pré-certificado' - imutavelmente para um log público confiável, por o objetivo da Transparência do Certificado .
PS: você também pode consultar https://security.stackexchange.com/questions/127095/manually-walking-through-the-signature-validation-of-a-certificate que detalha um processo semelhante usando o openssl.