private byte[] Decrypt(byte[] Message, byte[] Parameters, bool usePrivate, bool fOAEP) { var EM = new byte[0]; try { if (usePrivate && UseCRTForPublicDecryption && rsaParams.HasCRTInfo) { EM = RSADecryptPrivateCRT(Message); } else { EM = RSAProcess(Message, usePrivate); } } catch (CryptographicException ex) { throw new CryptographicException("Exception while Decryption: " + ex.Message); } catch { throw new Exception("Exception while Decryption: "); } try { if (fOAEP) //DECODE OAEP { if ((EM.Length == rsaParams.OctetsInModulus) && (EM.Length > 2 * rsaParams.hLen + 1)) { byte[] maskedSeed; byte[] maskedDB; var pHash = rsaParams.ComputeHash(Parameters); if (EM[0] == 0) // RFC3447 Format : http://tools.ietf.org/html/rfc3447 { maskedSeed = EM.ToList().GetRange(1, rsaParams.hLen).ToArray(); maskedDB = EM.ToList().GetRange(1 + rsaParams.hLen, EM.Length - rsaParams.hLen - 1).ToArray(); var seedMask = MGF(maskedDB, rsaParams.hLen); var seed = RSAProviderUtils.XOR(maskedSeed, seedMask); var dbMask = MGF(seed, rsaParams.OctetsInModulus - rsaParams.hLen - 1); var DB = RSAProviderUtils.XOR(maskedDB, dbMask); if (DB.Length >= rsaParams.hLen + 1) { var _pHash = DB.ToList().GetRange(0, rsaParams.hLen).ToArray(); var PS_M = DB.ToList().GetRange(rsaParams.hLen, DB.Length - rsaParams.hLen); var pos = PS_M.IndexOf(0x01); if (pos >= 0 && (pos < PS_M.Count)) { var _01_M = PS_M.GetRange(pos, PS_M.Count - pos); byte[] M; if (_01_M.Count > 1) { M = _01_M.GetRange(1, _01_M.Count - 1).ToArray(); } else { M = new byte[0]; } var success = true; for (var i = 0; i < rsaParams.hLen; i++) { if (_pHash[i] != pHash[i]) { success = false; break; } } if (success) { return(M); } M = new byte[rsaParams.OctetsInModulus]; //Hash Match Failure. throw new CryptographicException("OAEP Decode Error"); } // #3: Invalid Encoded Message Length. throw new CryptographicException("OAEP Decode Error"); } // #2: Invalid Encoded Message Length. throw new CryptographicException("OAEP Decode Error"); } //OAEP : THIS STADNARD IS NOT IMPLEMENTED throw new CryptographicException("OAEP Decode Error"); } // #1: Invalid Encoded Message Length. throw new CryptographicException("OAEP Decode Error"); } if (EM.Length >= 11) { if ((EM[0] == 0x00) && (EM[1] == 0x02)) { var startIndex = 2; var PS = new List <byte>(); for (var i = startIndex; i < EM.Length; i++) { if (EM[i] != 0) { PS.Add(EM[i]); } else { break; } } if (PS.Count >= 8) { var DecodedDataIndex = startIndex + PS.Count + 1; if (DecodedDataIndex < EM.Length - 1) { var DATA = new List <byte>(); for (var i = DecodedDataIndex; i < EM.Length; i++) { DATA.Add(EM[i]); } return(DATA.ToArray()); } return(new byte[0]); //throw new CryptographicException("PKCS v1.5 Decode Error #4: No Data"); } // #3: Invalid Key / Invalid Random Data Length throw new CryptographicException("PKCS v1.5 Decode Error"); } // #2: Invalid Key / Invalid Identifiers throw new CryptographicException("PKCS v1.5 Decode Error"); } // #1: Invalid Key / PKCS Encoding throw new CryptographicException("PKCS v1.5 Decode Error"); } catch (CryptographicException ex) { throw new CryptographicException("Exception while decoding: " + ex.Message); } catch { throw new CryptographicException("Exception while decoding"); } }
private byte[] RSAProcessEncodeOAEP(byte[] M, byte[] P, bool usePrivate) { // +----------+---------+-------+ // DB = | lHash | PS | M | // +----------+---------+-------+ // | // +----------+ V // | seed |--> MGF ---> XOR // +----------+ | // | | // +--+ V | // |00| XOR <----- MGF <-----| // +--+ | | // | | | // V V V // +--+----------+----------------------------+ // EM = |00|maskedSeed| maskedDB | // +--+----------+----------------------------+ var mLen = M.Length; if (mLen > rsaParams.OctetsInModulus - 2 * rsaParams.hLen - 2) { throw new ArgumentException("Message too long."); } var PS = new byte[rsaParams.OctetsInModulus - mLen - 2 * rsaParams.hLen - 2]; //4. pHash = Hash(P), var pHash = rsaParams.ComputeHash(P); //5. DB = pHash||PS||01||M. var _DB = new List <byte>(); _DB.AddRange(pHash); _DB.AddRange(PS); _DB.Add(0x01); _DB.AddRange(M); var DB = _DB.ToArray(); //6. Generate a random octet string seed of length hLen. var seed = new byte[rsaParams.hLen]; rng.GetBytes(seed); //7. dbMask = MGF(seed, k - hLen -1). var dbMask = MGF(seed, rsaParams.OctetsInModulus - rsaParams.hLen - 1); //8. maskedDB = DB XOR dbMask var maskedDB = RSAProviderUtils.XOR(DB, dbMask); //9. seedMask = MGF(maskedDB, hLen) var seedMask = MGF(maskedDB, rsaParams.hLen); //10. maskedSeed = seed XOR seedMask. var maskedSeed = RSAProviderUtils.XOR(seed, seedMask); //11. EM = 0x00 || maskedSeed || maskedDB. var result = new List <byte>(); result.Add(0x00); result.AddRange(maskedSeed); result.AddRange(maskedDB); return(RSAProcess(result.ToArray(), usePrivate)); }