Wie

2017-10-26 5 views
1

mit rsa von PEM-Datei entschlüsseln wir den folgenden C# -Code sind mit mit rsa mit PEM-Dateien zu verschlüsseln und entschlüsseln:Wie

public string encrypt(string elementToEncrypt, string pathPrivateKey) { 
     string pem = System.IO.File.ReadAllText(pathPrivateKey); 
     byte[] Buffer = getBytesFromPEMFile(pem, "PUBLIC KEY"); 
     System.Security.Cryptography.RSACryptoServiceProvider rsa = new System.Security.Cryptography.RSACryptoServiceProvider(); 
     System.Security.Cryptography.RSAParameters rsaParam = rsa.ExportParameters(false); 
     rsaParam.Modulus = Buffer; 
     rsa.ImportParameters(rsaParam); 
     byte[] encryptedMessageByte = rsa.Encrypt(Convert.FromBase64String(elementToEncrypt),false); 
     return Convert.ToBase64String(encryptedMessageByte); 
    } 

public string decrypt(string elementToDesencrypt, string pathPublicKey) 
    { 
     string pem = System.IO.File.ReadAllText(pathPublicKey); 
     byte[] Buffer = getBytesFromPEMFile(pem, "RSA PRIVATE KEY"); 
     System.Security.Cryptography.RSACryptoServiceProvider rsa = new System.Security.Cryptography.RSACryptoServiceProvider(); 
     System.Security.Cryptography.RSAParameters rsaParam = rsa.ExportParameters(false); 
     rsaParam.Modulus = Buffer; 
     rsa.ImportParameters(rsaParam); 
     byte[] encryptedMessageByte = rsa.Decrypt(Convert.FromBase64String(elementToDesencrypt), false); 
     return Convert.ToBase64String(encryptedMessageByte); 
    } 

public byte[] getBytesFromPEMFile(string pemString, string headerPEM) { 
     string header = String.Format("-----BEGIN {0}-----", headerPEM); 
     string footer = String.Format("-----END {0}-----", headerPEM); 
     int start = pemString.IndexOf(header, StringComparison.Ordinal) + header.Length; 
     int end = pemString.IndexOf(footer, start, StringComparison.Ordinal) - start; 
     if (start < 0 || end < 0) 
     { 
      return null; 
     } 
     return Convert.FromBase64String(pemString.Substring(start, end)); 
    } 

Aber das Problem ist, wenn ich in der Leitung entschlüsseln mag:

byte[] encryptedMessageByte = rsa.Decrypt(Convert.FromBase64String(elementToDesencrypt), false); 

und der Fehler, den ich bekomme, ist, dass der Schlüssel nicht existiert. enter image description here

Meine pem Dateien sind:

key.pem

-----BEGIN RSA PRIVATE KEY----- 
MIICXAIBAAKBgQDLPKI8p+ANRabCTdLvJjuT0wx1kt2voJ0+BtdTRBqhJQbRgM2P 
dtHilmaVSyiVtD5l1mTl+h8mFRBttiH0VgW3KuyvFk2mrjF78MrsXlYoHVizGgeh 
UWVUsNh7EhdgF/hM7miZMXsHoa/MEQwgytPwjpDbOXXECZz8CpHiyNOftwIDAQAB 
AoGAUrmXgAEFHeHgAu8SkO2LCpy5UZI6UiaaWokGVIpAHJ+pqtU21tKSlByMHPC+ 
0FDRpTojT8kDrMieK0obgA0TvcUaARVPGZsLjB4WZLKh7e8LPaUTvAS9dTmKd7xB 
4YGFKY+AJb38VdDU9CoQMsiPtIIiPWz09lgGvYRGzXmTBwECQQDsEtLRyOijXISK 
iFhtdpBI4yAmnTYyYLrsPXgS7asa80h7vnTmOlUpuqsxZtWNVGcpNiYG4y8OpJU5 
Jr8IkNnXAkEA3GRC63+SEbEo5wXcrHF+tzxfFmk3yzS38w5jtGik3yrp6psyjaQ8 
Q+D3RaKjGYtjTH3pmljRH2OGEvrNwvFtIQJAFkLgJnAvn9gFl5qr3AamLHleesWw 
aqe8eLKDNCW9UNlIKIMZOuydQ0YbBpmP4bfn0ncMtvGNanASskT5FrGyGQJASE7k 
3dsnE4LqhpGXy0QZbQjzsain05XiXG52K/TBUy8DPCPbPDmMREEFH+WyWWkwFSKi 
iC9nvUKr9IIxDCqlwQJBAIDwEg6yVGdVCQry+OEGtsiaGPveX+lAx/kULba0wfRq 
KaQAstQrT7p+ONtC8x8NHDE/ayjz6GlEZ7svR/LZO7w= 
-----END RSA PRIVATE KEY----- 

und pubkey.pem

-----BEGIN PUBLIC KEY----- 
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLPKI8p+ANRabCTdLvJjuT0wx1 
kt2voJ0+BtdTRBqhJQbRgM2PdtHilmaVSyiVtD5l1mTl+h8mFRBttiH0VgW3Kuyv 
Fk2mrjF78MrsXlYoHVizGgehUWVUsNh7EhdgF/hM7miZMXsHoa/MEQwgytPwjpDb 
OXXECZz8CpHiyNOftwIDAQAB 
-----END PUBLIC KEY----- 

ich gelesen habe, dass, wenn ich entschlüsseln will, muss ich beide haben sollte Schlüssel in eine PEM-Datei, aber wenn ich es tue, wüsste ich nicht, was ich anziehen soll

rsaParam.Modulus = Buffer; 

Ich meine, muss ich beide Puffer (privat und öffentlich) in einem mischen? Wenn ja, wie soll ich das machen?

Danke für die Hilfe.

Antwort

0

.NET verfügt nicht über integrierte Unterstützung zum Lesen von "bare-key" -Dateien.

Wenn Sie die Base64-Komponente Ihres öffentlichen Schlüsseldatei https://lapo.it/asn1js/ fügen Sie werden sehen, dass es

SEQUENCE 
    SEQUENCE 
    OBJECT IDENTIFIER rsaEncryption 
    NULL 
    BIT STRING 
    SEQUENCE 
     INTEGER (1024-bit) ... 
     INTEGER 65537 

zu

zerlegt werden kann es in .NET zu importieren, müssen Sie die Bytes (nicht kopieren der Dezimalwert) der ersten Ganzzahl (1024-Bit in diesem Beispiel) in den RSAParameters.Modulus-Wert und die Bytes der zweiten Ganzzahl in den RSAParameters.Exponent-Wert. In beiden Fällen, wenn es ein führendes 00-Byte gibt, müssen Sie das weglassen.

Für Ihre aktuellen Schlüssel:

RSAParameters rsaParams = new RSAParameters 
{ 
    Modulus = YourFavoriteHexParser(
     "CB3CA23CA7E00D45A6C24DD2EF263B93D30C7592DDAFA09D3E06D753441AA125" + 
     "06D180CD8F76D1E29666954B2895B43E65D664E5FA1F2615106DB621F45605B7" + 
     "2AECAF164DA6AE317BF0CAEC5E56281D58B31A07A1516554B0D87B12176017F8" + 
     "4CEE6899317B07A1AFCC110C20CAD3F08E90DB3975C4099CFC0A91E2C8D39FB7"), 
    Exponent = new byte[] { 0x01, 0x00, 0x01 }, 
}; 

RSA rsa = RSA.Create(); 
rsa.ImportParameters(rsaParams); 
return rsa; 

allgemeine, müßten Sie die öffentliche Schlüssel-Datei als ASN.1 DES Blob zu analysieren, dann die Modulus und Exponenten Werte aus der Nutzlast verbrauchen.

Die einfachste Problemumgehung, wenn Sie dies mehr als einmal tun müssen, ist die Verwendung von OpenSSL, um ein selbstsigniertes Zertifikat für die Schlüsseldatei zu erstellen, da .NET Schlüssel aus Zertifikaten verwenden kann (cert.GetRSAPublicKey()).

Hinzufügen von Unterstützung für bare Schlüssel ist in der .NET Core-Roadmap (https://github.com/dotnet/corefx/issues/20414), und man kann vernünftigerweise davon ausgehen, dass, nachdem es zu .NET Core hinzugefügt wird, es .NET Framework wird.

Zum Entschlüsseln benötigen Sie den privaten Schlüssel. Die einfachste Antwort besteht wiederum darin, ein selbstsigniertes Zertifikat aus dem Schlüssel zu erstellen, das Zertifikat und den Schlüssel in einer PFX/PKCS # 12-Datei zusammenzufassen und cert.GetRSAPrivateKey() zu verwenden.Aber für die harte Art und Weise:

den privaten Schlüssel blob einfügen sehen wir, dass es aussieht wie

SEQUENCE 
    INTEGER 0 
    INTEGER (1024-bit) 
    INTEGER 65537 
    INTEGER (1023-bit) 
    INTEGER (512-bit) 
    INTEGER (512-bit) 
    INTEGER (509-bit) 
    INTEGER (511-bit) 
    INTEGER (512-bit) 

In https://tools.ietf.org/html/rfc8017#appendix-A.1.2 wir sehen, dass die RSAPrivateKey Struktur sieht wie

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 

Und diese Version = = 0 bedeutet, dass es nur zwei Primzahlen gibt. Jetzt stoßen wir auf einige Macken. In .NET muss der Wert D die gleiche Größe wie Modulus haben. Wenn zufällig auf eine "1016-Bit" -Nummer (oder kleiner) kommt, müssen Sie die führenden 0x00 Werte eingeben. .NET erfordert auch, dass P genau die halbe Größe von Modulus (aufgerundet, wenn es darauf ankommt), und dass Q, DP, und InverseQ alle die gleiche Größe wie P haben.

Also noch einmal für Ihren Schlüssel:

RSAParameters rsaParams = new RSAParameters 
{ 
    Modulus = YourFavoriteHexParser(
     "CB3CA23CA7E00D45A6C24DD2EF263B93D30C7592DDAFA09D3E06D753441AA125" + 
     "06D180CD8F76D1E29666954B2895B43E65D664E5FA1F2615106DB621F45605B7" + 
     "2AECAF164DA6AE317BF0CAEC5E56281D58B31A07A1516554B0D87B12176017F8" + 
     "4CEE6899317B07A1AFCC110C20CAD3F08E90DB3975C4099CFC0A91E2C8D39FB7"), 
    Exponent = new byte[] { 0x01, 0x00, 0x01 }, 
    D = YourFavoriteHexParser(
     "52B9978001051DE1E002EF1290ED8B0A9CB951923A52269A5A8906548A401C9F" + 
     "A9AAD536D6D292941C8C1CF0BED050D1A53A234FC903ACC89E2B4A1B800D13BD" + 
     "C51A01154F199B0B8C1E1664B2A1EDEF0B3DA513BC04BD75398A77BC41E18185" + 
     "298F8025BDFC55D0D4F42A1032C88FB482223D6CF4F65806BD8446CD79930701"), 
    P = YourFavoriteHexParser(
     "EC12D2D1C8E8A35C848A88586D769048E320269D363260BAEC3D7812EDAB1AF3" + 
     "487BBE74E63A5529BAAB3166D58D546729362606E32F0EA4953926BF0890D9D7"), 
    Q = YourFavoriteHexParser(
     "DC6442EB7F9211B128E705DCAC717EB73C5F166937CB34B7F30E63B468A4DF2A" + 
     "E9EA9B328DA43C43E0F745A2A3198B634C7DE99A58D11F638612FACDC2F16D21"), 
    DP = YourFavoriteHexParser(
     "1642E026702F9FD805979AABDC06A62C795E7AC5B06AA7BC78B2833425BD50D9" + 
     "482883193AEC9D43461B06998FE1B7E7D2770CB6F18D6A7012B244F916B1B219"), 
    DQ = YourFavoriteHexParser(
     "484EE4DDDB271382EA869197CB44196D08F3B1A8A7D395E25C6E762BF4C1532F" + 
     "033C23DB3C398C4441051FE5B25969301522A2882F67BD42ABF482310C2AA5C1"), 
    InverseQ = YourFavoriteHexParser(
     "80F0120EB2546755090AF2F8E106B6C89A18FBDE5FE940C7F9142DB6B4C1F46A" + 
     "29A400B2D42B4FBA7E38DB42F31F0D1C313F6B28F3E8694467BB2F47F2D93BBC"), 
}; 

RSA rsa = RSA.Create(); 
rsa.ImportParameters(rsaParams); 
return rsa;