Je connais la réponse principale que je suis susceptible d'obtenir c'est pourquoi diable voudriez-vous faire ça ?!
Malheureusement malgré mes manifestations, je dois le faire, même si je sais que cela a peu de sens. P>
J'ai des fonctions écrites dans .NET à Decrypt en utilisant une clé privée, chiffrer à l'aide d'une clé publique. Je signe également RSA et vérifie et j'ai une compréhension raisonnable de la façon dont tout ce travail que je pense. P>
Je suis maintenant envoyé une valeur RSA cryptée à l'aide d'une clé privée que je suis censé dériver une valeur utilisable. En décryptant en utilisant la clé publique. P>
Je n'arrive pas à comprendre comment faire cela. Suis-je un idiot? Est-ce une chose normale à faire? P>
On me dit que la personne m'envoyait la valeur que ce n'est pas un problème dans PHP. Je ne sais pas et je n'ai pas encore utilisé php. Je ne trouve pas une bibliothèque pour le faire dans l'une des langues principales que je connais I.e. C ++, Java, C #. Le serveur que je travaille sur utilise .NET. P>
J'espère que quelqu'un pourrait peut-être m'aider. p>
Ce serait formidable s'il ya une sorte de solution raisonnable en plus de les supplier de changer ce qu'ils font. P>
C'est ma méthode (mise à jour de mon précédent mauvais omes par Iridium) mais lorsque j'essaie de déchiffrer la valeur, une erreur d'exception p>
"s'est produite lors du décodage du remplissage OAEP." p>
Si j'utilise rsa.decrypt (octets, false) i Obtenez une mauvaise exception de clé. P>
public static string DecryptUsingPublic(string dataEncrypted, string publicKey) { if (dataEncrypted == null) throw new ArgumentNullException("dataEncrypted"); if (publicKey == null) throw new ArgumentNullException("publicKey"); try { RSAParameters _publicKey = LoadRsaPublicKey(publicKey, false); RSACryptoServiceProvider rsa = InitRSAProvider(_publicKey); byte[] bytes = Convert.FromBase64String(dataEncrypted); byte[] decryptedBytes = rsa.Decrypt(bytes, true); ArrayList arrayList = new ArrayList(); arrayList.AddRange(decryptedBytes); return Encoding.UTF8.GetString(decryptedBytes); } catch { return null; } } private static RSAParameters LoadRsaPublicKey(String publicKeyFilePath, Boolean isFile) { RSAParameters RSAKeyInfo = new RSAParameters(); byte[] pubkey = ReadFileKey(publicKeyFilePath, "PUBLIC KEY", isFile); byte[] SeqOID = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 }; byte[] seq = new byte[15]; // --------- Set up stream to read the asn.1 encoded SubjectPublicKeyInfo blob ------ MemoryStream mem = new MemoryStream(pubkey); BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading byte bt = 0; ushort twobytes = 0; try { twobytes = binr.ReadUInt16(); if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81) binr.ReadByte(); //advance 1 byte else if (twobytes == 0x8230) binr.ReadInt16(); //advance 2 bytes else return RSAKeyInfo; seq = binr.ReadBytes(15); //read the Sequence OID if (!CompareBytearrays(seq, SeqOID)) //make sure Sequence for OID is correct return RSAKeyInfo; twobytes = binr.ReadUInt16(); if (twobytes == 0x8103) //data read as little endian order (actual data order for Bit String is 03 81) binr.ReadByte(); //advance 1 byte else if (twobytes == 0x8203) binr.ReadInt16(); //advance 2 bytes else return RSAKeyInfo; bt = binr.ReadByte(); if (bt != 0x00) //expect null byte next return RSAKeyInfo; twobytes = binr.ReadUInt16(); if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81) binr.ReadByte(); //advance 1 byte else if (twobytes == 0x8230) binr.ReadInt16(); //advance 2 bytes else return RSAKeyInfo; twobytes = binr.ReadUInt16(); byte lowbyte = 0x00; byte highbyte = 0x00; if (twobytes == 0x8102) //data read as little endian order (actual data order for Integer is 02 81) lowbyte = binr.ReadByte(); // read next bytes which is bytes in modulus else if (twobytes == 0x8202) { highbyte = binr.ReadByte(); //advance 2 bytes lowbyte = binr.ReadByte(); } else return RSAKeyInfo; byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; //reverse byte order since asn.1 key uses big endian order int modsize = BitConverter.ToInt32(modint, 0); byte firstbyte = binr.ReadByte(); binr.BaseStream.Seek(-1, SeekOrigin.Current); if (firstbyte == 0x00) { //if first byte (highest order) of modulus is zero, don't include it binr.ReadByte(); //skip this null byte modsize -= 1; //reduce modulus buffer size by 1 } byte[] modulus = binr.ReadBytes(modsize); //read the modulus bytes if (binr.ReadByte() != 0x02) //expect an Integer for the exponent data return RSAKeyInfo; int expbytes = (int)binr.ReadByte(); // should only need one byte for actual exponent data (for all useful values) byte[] exponent = binr.ReadBytes(expbytes); RSAKeyInfo.Modulus = modulus; RSAKeyInfo.Exponent = exponent; return RSAKeyInfo; } catch (Exception) { return RSAKeyInfo; } finally { binr.Close(); } //return RSAparams; } private static RSACryptoServiceProvider InitRSAProvider(RSAParameters rsaParam) { // // Initailize the CSP // Supresses creation of a new key // CspParameters csp = new CspParameters(); //csp.KeyContainerName = "RSA Test (OK to Delete)"; const int PROV_RSA_FULL = 1; csp.ProviderType = PROV_RSA_FULL; const int AT_KEYEXCHANGE = 1; // const int AT_SIGNATURE = 2; csp.KeyNumber = AT_KEYEXCHANGE; // // Initialize the Provider // RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(csp); rsa.PersistKeyInCsp = false; // // The moment of truth... // rsa.ImportParameters(rsaParam); return rsa; } private static int GetIntegerSize(BinaryReader binr) { byte bt = 0; byte lowbyte = 0x00; byte highbyte = 0x00; int count = 0; bt = binr.ReadByte(); if (bt != 0x02) //expect integer return 0; bt = binr.ReadByte(); if (bt == 0x81) count = binr.ReadByte(); // data size in next byte else if (bt == 0x82) { highbyte = binr.ReadByte(); // data size in next 2 bytes lowbyte = binr.ReadByte(); byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; count = BitConverter.ToInt32(modint, 0); } else { count = bt; // we already have the data size } while (binr.ReadByte() == 0x00) { //remove high order zeros in data count -= 1; } binr.BaseStream.Seek(-1, SeekOrigin.Current); //last ReadByte wasn't a removed zero, so back up a byte return count; } private static bool CompareBytearrays(byte[] a, byte[] b) { if (a.Length != b.Length) return false; int i = 0; foreach (byte c in a) { if (c != b[i]) return false; i++; } return true; }
3 Réponses :
RSA est intégrée dans .NET:. Encrypting en utilisant la clé publique et avec la clé de décryptage privée est l'une des choses les plus communes que les gens font avec des algorithmes asymétriques, il permet à chacun de vous envoyer quelque chose en toute sécurité. p>
Si vous le faites dans l'autre sens: Crypter avec la clé privée, et décrypter avec la clé publique alors il prouve le message a été envoyé par le titulaire de la clé privée. Mais parce que tout le monde peut sans doute mettre la main sur la clé publique, les gens ont tendance à ne pas chiffrer le message entier, ils signent plutôt juste un hachage des données à l'aide de la clé privée. Par conséquent Pourtant, il y a Dire que j'ai trouvé les cours de Microsoft Crypto un peu difficile à traiter et manque dans certains domaines et beaucoup préfèrent la Bouncy bibliothèques Château . p> System.Security.Cryptography.RSA code> p>
RSACryptoServiceProvider code> a
__ Connexion code> et
Vérifier __ code> pour le faire. p>
Crypter / Décrypter code> si votre partenaire insiste sur le fait. P>
Désolé je suis un idiot. J'ai eu ma question complètement en arrière. Je l'ai édité pour montrer ce que je voulais dire.
Je pensais alors! Mise à jour de la réponse.
Merci beaucoup pour votre réponse. Je ne peux pas sembler obtenir la méthode Decrypt pour travailler dans ce cas. J'ai mis à jour ma question à montrer où cela va mal. Je fais probablement quelque chose de stupide et marquera cela comme la réponse dès que je trouve ce que c'est.
Ajout d'une suggestion d'essayer les bibliothèques du château gonflable - ils ont tendance à inter-opérer avec le monde non MS un peu mieux.
Va regarder dans le château de Bouncy. Merci pour votre suggestion.
Après avoir examiné certaines des informations sur les modes de cryptage RSA, il semblerait que PKCS # 1 v1.5 (que vous utilisez, parce que vous appelez "... peut fonctionner sur des messages de longueur jusqu'à k - 11 octets em> strong> (k est la longueur d'octet du module RSA)" p>
Blockquote> (RFC 3447, Souligné par l'auteur) p> D'après le message d'erreur, ce qui indique que la clé est de 128 octets, cela signifie que vous ne pouvez pas effectuer RSA (en |. De ) Cryption utilisant PKCS # 1 v1.5 sur un message avec plus de 128 -. 11 = 117 octets p> au lieu de chiffrer votre message directement en utilisant RSA, vous devez utiliser un algorithme symétrique pour chiffrer le corps le message et chiffrent uniquement la clé de chiffrement symétrique en utilisant RSA. Seulement si votre message est raisonnablement court (par exemple ci-dessous 117 octets pour votre taille de la clé) devrait vous envisager de chiffrer le message directement avec RSA. P> J'ai ajouté ce qui suit, en supposant que votre entrée est codé en Base64 que vous indiquez dans votre commentaire ci-dessous: p> Décrypter (..., false) code>)
public string DecryptUsingPublic(string dataEncryptedBase64, string publicKey)
{
if (dataEncryptedBase64 == null) throw new ArgumentNullException("dataEncryptedBase64");
if (publicKey == null) throw new ArgumentNullException("publicKey");
try
{
RSAParameters _publicKey = LoadRsaPublicKey(publicKey, false);
RSACryptoServiceProvider rsa = InitRSAProvider(_publicKey);
byte[] bytes = Convert.FromBase64String(dataEncryptedBase64);
byte[] decryptedBytes = rsa.Decrypt(bytes, false);
// I assume here that the decrypted data is intended to be a
// human-readable string, and that it was UTF8 encoded.
return Encoding.UTF8.GetString(decryptedBytes);
}
catch
{
return null;
}
}
Merci pour votre réponse. J'ai lu RFC 3447 toute la journée en essayant de trouver une solution. Le principal problème est que je n'ai aucun contrôle sur la manière dont la valeur est cryptée. Fondamentalement, je reçois une valeur i.e. valeur = base64 [rsa_private_encrypt (quelque_text)] Il m'a été laissé à comprendre comment décrypter et utiliser cette valeur. J'ai essayé beaucoup de choses mais pas de joie. J'ai demandé un exemple de travail pour le déchiffrement de la personne qui m'envoie la valeur. Si je l'obtiens, je le posterai ici.
Ce n'est pas ce que votre code de code suggère, car vous n'avez pas de décodage de base64. (Vous ne devriez pas utiliser Encoding.Actentii à cet effet soit, car il est seulement 7 bits). Si votre entrée est base64, vous devez utiliser Convert.frombase64String (datacrypted) pour obtenir un tableau d'octets à utiliser avec les fonctions RSA.
Bien que ma réponse d'origine s'applique toujours, j'ai ajouté du code à ma réponse qui peut corriger votre problème, en fonction de l'hypothèse que l'entrée est en fait de base64 codée comme indiqué dans votre commentaire ci-dessus.
Merci. Vous avez raison. J'étais censé utiliser la base64. C'était une erreur stupide commise comme j'essayais d'inverser la méthode de chiffrement. J'ai mis à jour ma question.
Enfin, utilisez-le en utilisant votre conseil et votre code source d'ici codeProject.com/kb/security/ PrivéCollection.aspx
RSA est non strong> destiné à chiffrer des données arbitraires, encore moins de longueur de données arbitraire (comme @iridium vous a déjà dit). La limite dépend du rembourrage utilisé et de l'utilisation du rembourrage est Le moyen L'autre partie sera en mesure de déchiffrer la clé Secret (AES) à l'aide de la clé privée RSA. Ensuite, utilisez la touche décrypte votre chaîne. P>
J'ai un vieux (mais toujours à jour) Entrée de blog sur Le sujet qui comprend fort> code source (C #). P> chiffrervalue code> et
déchiffsvalue code> directement) . p>
Merci pour votre réponse. Je suis complètement d'accord avec toi. Le problème est que je ne chiffre pas la valeur. J'ai une clé privée et une clé publique. Je suis envoyé une valeur qui a été cryptée à l'aide de la clé privée et je dois maintenant comprendre comment la déchiffrer. Cela peut ne pas avoir de sens et il peut ne pas y avoir une solution simple, mais je ne suis pas très expérimenté avec cela, donc j'apprécie tous les commentaires et suggestions.
Si vous êtes coincé sur la touche Diffrigation B>, vous n'avez pas de choix (sûr ou non) que de faire les opérations inverse pour récupérer les données. J'espère que cela ne vous obligera pas à utiliser déchiffsvalue code> (il ne doit pas si l'autre, crypter, utilisation de la partie .NET), mais même alors il y a des solutions pour cela :) Faites-nous savoir!
Je ne comprends pas cela de votre blog il a également un sens "Security wise" car une clé symétrique de 128 bits est plus sécurisée qu'un clavier asymétrique de 1024 bits (au moins pour RSA) code>. Pourriez-vous expliquer plus sur la manière dont AES est plus sécurisé que RSA?
Il ne s'agit pas de AES ou de RSA eux-mêmes (trop différent), il s'agit de la longueur de la clé utilisée pour les deux (c'est-à-dire que c'est difficile de les casser). Je dois être I> plus facile à casser RSA 1024 que l'AES 128. Suggéré a suggéré de lire Security.stackexchange.com/questions/38015/...
Tu peux répéter s'il te plait? C'est exactement ce que l'algorithme est censé faire. Décrypte en utilisant une clé privée Qu'est-ce qui a été crypté à l'aide de la clé publique correspondante. Soit tu es confus gros fois ou je suis! C # favorise parfaitement RSA :)
Désolé. Édité ma question. Je l'ai écrit complètement mal. Le cerveau commence à brouiller un peu le vendredi.
Qu'est-ce que tu ne peux pas comprendre? Vous dites que vous avez déjà des fonctions pour déchiffrer avec une clé publique.
D'accord, désolé. J'aurais dû lire ma question correctement. Fait un gâchis total de celui-ci. J'ai le déchiffrement standard avec une clé privée et non publique. Si j'essaie de déchiffrer la valeur cryptée à l'aide de la clé privée avec la clé publique, je reçois une exception - les données à déchiffrer dépassent le maximum de ce module de 128 octets. J'ai cherché à essayer beaucoup de choses, mais je continue à obtenir des exceptions.
Que font LoadrsapublicKey et InitirsAprovider? Pouvez-vous aussi fournir le code de ces méthodes aussi?
Bien sûr, le code est assez long mais je vais l'ajouter. Les clés sont des clés PEM issues d'une base de données comme chaînes.
Hey, j'ai le même problème essayé votre code, mais il n'existe toujours pas que la clé n'existe pas, quelle est exactement Listerfilekey Looke, quel est le format de votre clé?
Désolé Oscar Cabrero. C'était un moment de retour et je ne me souviens pas des détails précis. Je sais que le code dans ma question est faux et n'a pas fonctionné. Je l'ai éventuellement résolu à l'aide de ce tutoriel: codeproject.com/kb/security/privatecryption.aspx et les détails de la réponse acceptée. Je regrette maintenant de ne pas poster toute ma solution. Je n'ai plus le code et je n'ai certainement pas de mémoire assez bon pour la reproduire correctement sans prendre un peu de temps. Quant à la clé, je lis cela comme une chaîne d'une base de données. J'ai reçu les clés que les fichiers PEM, copié les valeurs à la base de données et lisez à partir de là.
Que référencez-vous pour "Readfilekey" ??
AVERTISSEMENT: B> Cryptage avec une clé privée et un déchiffrement avec une clé publique est intrinsèquement dangereux et n'est pas identique à la génération / vérification de la signature. Ok, vous avez été averti, vous pouvez continuer à vous tirer au pied maintenant.