C#的BouncyCastle.Crypto,RSA算法调用的源码,正在研究这个,分享给大家。
官网:
1 using System; 2 3 using NUnit.Framework; 4 5 using Org.BouncyCastle.Crypto; 6 using Org.BouncyCastle.Crypto.Digests; 7 using Org.BouncyCastle.Crypto.Encodings; 8 using Org.BouncyCastle.Crypto.Engines; 9 using Org.BouncyCastle.Crypto.Generators; 10 using Org.BouncyCastle.Crypto.Parameters; 11 using Org.BouncyCastle.Math; 12 using Org.BouncyCastle.Security; 13 using Org.BouncyCastle.Utilities; 14 using Org.BouncyCastle.Utilities.Encoders; 15 using Org.BouncyCastle.Utilities.Test; 16 17 namespace Org.BouncyCastle.Crypto.Tests 18 { 19 [TestFixture] 20 public class RsaTest 21 : SimpleTest 22 { 23 static BigInteger mod = new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16); 24 static BigInteger pubExp = new BigInteger("11", 16); 25 static BigInteger privExp = new BigInteger("92e08f83cc9920746989ca5034dcb384a094fb9c5a6288fcc4304424ab8f56388f72652d8fafc65a4b9020896f2cde297080f2a540e7b7ce5af0b3446e1258d1dd7f245cf54124b4c6e17da21b90a0ebd22605e6f45c9f136d7a13eaac1c0f7487de8bd6d924972408ebb58af71e76fd7b012a8d0e165f3ae2e5077a8648e619", 16); 26 static BigInteger p = new BigInteger("f75e80839b9b9379f1cf1128f321639757dba514642c206bbbd99f9a4846208b3e93fbbe5e0527cc59b1d4b929d9555853004c7c8b30ee6a213c3d1bb7415d03", 16); 27 static BigInteger q = new BigInteger("b892d9ebdbfc37e397256dd8a5d3123534d1f03726284743ddc6be3a709edb696fc40c7d902ed804c6eee730eee3d5b20bf6bd8d87a296813c87d3b3cc9d7947", 16); 28 static BigInteger pExp = new BigInteger("1d1a2d3ca8e52068b3094d501c9a842fec37f54db16e9a67070a8b3f53cc03d4257ad252a1a640eadd603724d7bf3737914b544ae332eedf4f34436cac25ceb5", 16); 29 static BigInteger qExp = new BigInteger("6c929e4e81672fef49d9c825163fec97c4b7ba7acb26c0824638ac22605d7201c94625770984f78a56e6e25904fe7db407099cad9b14588841b94f5ab498dded", 16); 30 static BigInteger crtCoef = new BigInteger("dae7651ee69ad1d081ec5e7188ae126f6004ff39556bde90e0b870962fa7b926d070686d8244fe5a9aa709a95686a104614834b0ada4b10f53197a5cb4c97339", 16); 31 32 static string input = "4e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"; 33 34 // 35 // to check that we handling byte extension by big number correctly. 36 // 37 static string edgeInput = "ff6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"; 38 39 static byte[] oversizedSig = Hex.Decode("01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff004e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"); 40 static byte[] dudBlock = Hex.Decode("000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff004e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"); 41 static byte[] truncatedDataBlock = Hex.Decode("0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff004e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"); 42 static byte[] incorrectPadding = Hex.Decode("0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"); 43 static byte[] missingDataBlock = Hex.Decode("0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); 44 45 public override string Name 46 { 47 get { return "RSA"; } 48 } 49 50 private void doTestStrictPkcs1Length(RsaKeyParameters pubParameters, RsaKeyParameters privParameters) 51 { 52 IAsymmetricBlockCipher eng = new RsaEngine(); 53 54 eng.Init(true, privParameters); 55 56 byte[] data = null; 57 58 try 59 { 60 data = eng.ProcessBlock(oversizedSig, 0, oversizedSig.Length); 61 } 62 catch (Exception e) 63 { 64 Fail("RSA: failed - exception " + e.ToString(), e); 65 } 66 67 eng = new Pkcs1Encoding(eng); 68 69 eng.Init(false, pubParameters); 70 71 try 72 { 73 data = eng.ProcessBlock(data, 0, data.Length); 74 75 Fail("oversized signature block not recognised"); 76 } 77 catch (InvalidCipherTextException e) 78 { 79 if (!e.Message.Equals("block incorrect size")) 80 { 81 Fail("RSA: failed - exception " + e.ToString(), e); 82 } 83 } 84 85 86 // Create the encoding with StrictLengthEnabled=false (done thru environment in Java version) 87 Pkcs1Encoding.StrictLengthEnabled = false; 88 89 eng = new Pkcs1Encoding(new RsaEngine()); 90 91 eng.Init(false, pubParameters); 92 93 try 94 { 95 data = eng.ProcessBlock(data, 0, data.Length); 96 } 97 catch (InvalidCipherTextException e) 98 { 99 Fail("RSA: failed - exception " + e.ToString(), e);100 }101 102 Pkcs1Encoding.StrictLengthEnabled = true;103 }104 105 private void doTestTruncatedPkcs1Block(RsaKeyParameters pubParameters, RsaKeyParameters privParameters)106 {107 checkForPkcs1Exception(pubParameters, privParameters, truncatedDataBlock, "block truncated");108 }109 110 private void doTestDudPkcs1Block(RsaKeyParameters pubParameters, RsaKeyParameters privParameters)111 {112 checkForPkcs1Exception(pubParameters, privParameters, dudBlock, "unknown block type");113 }114 115 private void doTestWrongPaddingPkcs1Block(RsaKeyParameters pubParameters, RsaKeyParameters privParameters)116 {117 checkForPkcs1Exception(pubParameters, privParameters, incorrectPadding, "block padding incorrect");118 }119 120 private void doTestMissingDataPkcs1Block(RsaKeyParameters pubParameters, RsaKeyParameters privParameters)121 {122 checkForPkcs1Exception(pubParameters, privParameters, missingDataBlock, "no data in block");123 }124 125 private void checkForPkcs1Exception(RsaKeyParameters pubParameters, RsaKeyParameters privParameters, byte[] inputData, string expectedMessage)126 {127 IAsymmetricBlockCipher eng = new RsaEngine();128 129 eng.Init(true, privParameters);130 131 byte[] data = null;132 133 try134 {135 data = eng.ProcessBlock(inputData, 0, inputData.Length);136 }137 catch (Exception e)138 {139 Fail("RSA: failed - exception " + e.ToString(), e);140 }141 142 eng = new Pkcs1Encoding(eng);143 144 eng.Init(false, pubParameters);145 146 try147 {148 data = eng.ProcessBlock(data, 0, data.Length);149 150 Fail("missing data block not recognised");151 }152 catch (InvalidCipherTextException e)153 {154 if (!e.Message.Equals(expectedMessage))155 {156 Fail("RSA: failed - exception " + e.ToString(), e);157 }158 }159 }160 161 private void doTestOaep(RsaKeyParameters pubParameters, RsaKeyParameters privParameters)162 {163 //164 // OAEP - public encrypt, private decrypt165 //166 IAsymmetricBlockCipher eng = new OaepEncoding(new RsaEngine());167 byte[] data = Hex.Decode(input);168 169 eng.Init(true, pubParameters);170 171 try172 {173 data = eng.ProcessBlock(data, 0, data.Length);174 }175 catch (Exception e)176 {177 Fail("failed - exception " + e.ToString(), e);178 }179 180 eng.Init(false, privParameters);181 182 try183 {184 data = eng.ProcessBlock(data, 0, data.Length);185 }186 catch (Exception e)187 {188 Fail("failed - exception " + e.ToString(), e);189 }190 191 if (!input.Equals(Hex.ToHexString(data)))192 {193 Fail("failed OAEP Test");194 }195 }196 197 // TODO Move this when other JCE tests are ported from Java198 /**199 * signature with a "forged signature" (sig block not at end of plain text)200 */201 private void doTestBadSig()//PrivateKey priv, PublicKey pub)202 {203 // Signature sig = Signature.getInstance("SHA1WithRSAEncryption", "BC");204 ISigner sig = SignerUtilities.GetSigner("SHA1WithRSAEncryption");205 // KeyPairGenerator fact;206 // KeyPair keyPair;207 // byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };208 209 // fact = KeyPairGenerator.getInstance("RSA", "BC");210 RsaKeyPairGenerator fact = new RsaKeyPairGenerator();211 212 // fact.initialize(768, new SecureRandom());213 RsaKeyGenerationParameters factParams = new RsaKeyGenerationParameters(214 // BigInteger.ValueOf(0x11), new SecureRandom(), 768, 25);215 BigInteger.ValueOf(3), new SecureRandom(), 768, 25);216 fact.Init(factParams);217 218 // keyPair = fact.generateKeyPair();219 //220 // PrivateKey signingKey = keyPair.getPrivate();221 // PublicKey verifyKey = keyPair.getPublic();222 AsymmetricCipherKeyPair keyPair = fact.GenerateKeyPair();223 224 AsymmetricKeyParameter priv = keyPair.Private;225 AsymmetricKeyParameter pub = keyPair.Public;226 227 // testBadSig(signingKey, verifyKey);228 229 230 231 232 233 // MessageDigest sha1 = MessageDigest.getInstance("SHA1", "BC");234 IDigest sha1 = DigestUtilities.GetDigest("SHA1");235 236 // Cipher signer = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");237 // IBufferedCipher signer = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");238 IAsymmetricBlockCipher signer = new Pkcs1Encoding(new RsaEngine());239 240 // signer.init(Cipher.ENCRYPT_MODE, priv);241 signer.Init(true, priv);242 243 // byte[] block = new byte[signer.getBlockSize()];244 // byte[] block = new byte[signer.GetBlockSize()];245 byte[] block = new byte[signer.GetInputBlockSize()];246 247 // sha1.update((byte)0);248 sha1.Update(0);249 250 // byte[] sigHeader = Hex.decode("3021300906052b0e03021a05000414");251 byte[] sigHeader = Hex.Decode("3021300906052b0e03021a05000414");252 // System.arraycopy(sigHeader, 0, block, 0, sigHeader.length);253 Array.Copy(sigHeader, 0, block, 0, sigHeader.Length);254 255 // sha1.digest(block, sigHeader.length, sha1.getDigestLength());256 sha1.DoFinal(block, sigHeader.Length);257 258 // System.arraycopy(sigHeader, 0, block,259 // sigHeader.length + sha1.getDigestLength(), sigHeader.length);260 Array.Copy(sigHeader, 0, block,261 sigHeader.Length + sha1.GetDigestSize(), sigHeader.Length);262 263 // byte[] sigBytes = signer.doFinal(block);264 byte[] sigBytes = signer.ProcessBlock(block, 0, block.Length);265 266 // Signature verifier = Signature.getInstance("SHA1WithRSA", "BC");267 ISigner verifier = SignerUtilities.GetSigner("SHA1WithRSA");268 269 // verifier.initVerify(pub);270 verifier.Init(false, pub);271 272 // verifier.update((byte)0);273 verifier.Update(0);274 275 // if (verifier.verify(sig))276 if (verifier.VerifySignature(sigBytes))277 {278 // fail("bad signature passed");279 Fail("bad signature passed");280 }281 }282 283 private void testZeroBlock(ICipherParameters encParameters, ICipherParameters decParameters)284 {285 IAsymmetricBlockCipher eng = new Pkcs1Encoding(new RsaEngine());286 287 eng.Init(true, encParameters);288 289 if (eng.GetOutputBlockSize() != ((Pkcs1Encoding)eng).GetUnderlyingCipher().GetOutputBlockSize())290 {291 Fail("PKCS1 output block size incorrect");292 }293 294 byte[] zero = new byte[0];295 byte[] data = null;296 297 try298 {299 data = eng.ProcessBlock(zero, 0, zero.Length);300 }301 catch (Exception e)302 {303 Fail("failed - exception " + e.ToString(), e);304 }305 306 eng.Init(false, decParameters);307 308 try309 {310 data = eng.ProcessBlock(data, 0, data.Length);311 }312 catch (Exception e)313 {314 Fail("failed - exception " + e.ToString(), e);315 }316 317 if (!Arrays.AreEqual(zero, data))318 {319 Fail("failed PKCS1 zero Test");320 }321 }322 323 public override void PerformTest()324 {325 RsaKeyParameters pubParameters = new RsaKeyParameters(false, mod, pubExp);326 RsaKeyParameters privParameters = new RsaPrivateCrtKeyParameters(mod, pubExp, privExp, p, q, pExp, qExp, crtCoef);327 byte[] data = Hex.Decode(edgeInput);328 329 //330 // RAW331 //332 IAsymmetricBlockCipher eng = new RsaEngine();333 334 eng.Init(true, pubParameters);335 336 try337 {338 data = eng.ProcessBlock(data, 0, data.Length);339 }340 catch (Exception e)341 {342 Fail("RSA: failed - exception " + e.ToString());343 }344 345 eng.Init(false, privParameters);346 347 try348 {349 data = eng.ProcessBlock(data, 0, data.Length);350 }351 catch (Exception e)352 {353 Fail("failed - exception " + e.ToString());354 }355 356 if (!edgeInput.Equals(Hex.ToHexString(data)))357 {358 Fail("failed RAW edge Test");359 }360 361 data = Hex.Decode(input);362 363 eng.Init(true, pubParameters);364 365 try366 {367 data = eng.ProcessBlock(data, 0, data.Length);368 }369 catch (Exception e)370 {371 Fail("failed - exception " + e.ToString());372 }373 374 eng.Init(false, privParameters);375 376 try377 {378 data = eng.ProcessBlock(data, 0, data.Length);379 }380 catch (Exception e)381 {382 Fail("failed - exception " + e.ToString());383 }384 385 if (!input.Equals(Hex.ToHexString(data)))386 {387 Fail("failed RAW Test");388 }389 390 //391 // PKCS1 - public encrypt, private decrypt392 //393 eng = new Pkcs1Encoding(eng);394 395 eng.Init(true, pubParameters);396 397 if (eng.GetOutputBlockSize() != ((Pkcs1Encoding)eng).GetUnderlyingCipher().GetOutputBlockSize())398 {399 Fail("PKCS1 output block size incorrect");400 }401 402 try403 {404 data = eng.ProcessBlock(data, 0, data.Length);405 }406 catch (Exception e)407 {408 Fail("failed - exception " + e.ToString());409 }410 411 eng.Init(false, privParameters);412 413 try414 {415 data = eng.ProcessBlock(data, 0, data.Length);416 }417 catch (Exception e)418 {419 Fail("failed - exception " + e.ToString());420 }421 422 if (!input.Equals(Hex.ToHexString(data)))423 {424 Fail("failed PKCS1 public/private Test");425 }426 427 //428 // PKCS1 - private encrypt, public decrypt429 //430 eng = new Pkcs1Encoding(((Pkcs1Encoding)eng).GetUnderlyingCipher());431 432 eng.Init(true, privParameters);433 434 try435 {436 data = eng.ProcessBlock(data, 0, data.Length);437 }438 catch (Exception e)439 {440 Fail("failed - exception " + e.ToString());441 }442 443 eng.Init(false, pubParameters);444 445 try446 {447 data = eng.ProcessBlock(data, 0, data.Length);448 }449 catch (Exception e)450 {451 Fail("failed - exception " + e.ToString());452 }453 454 if (!input.Equals(Hex.ToHexString(data)))455 {456 Fail("failed PKCS1 private/public Test");457 }458 459 testZeroBlock(pubParameters, privParameters);460 testZeroBlock(privParameters, pubParameters);461 462 //463 // key generation test464 //465 RsaKeyPairGenerator pGen = new RsaKeyPairGenerator();466 RsaKeyGenerationParameters genParam = new RsaKeyGenerationParameters(467 BigInteger.ValueOf(0x11), new SecureRandom(), 768, 25);468 469 pGen.Init(genParam);470 471 AsymmetricCipherKeyPair pair = pGen.GenerateKeyPair();472 473 eng = new RsaEngine();474 475 if (((RsaKeyParameters)pair.Public).Modulus.BitLength < 768)476 {477 Fail("failed key generation (768) length test");478 }479 480 eng.Init(true, pair.Public);481 482 try483 {484 data = eng.ProcessBlock(data, 0, data.Length);485 }486 catch (Exception e)487 {488 Fail("failed - exception " + e.ToString());489 }490 491 eng.Init(false, pair.Private);492 493 try494 {495 data = eng.ProcessBlock(data, 0, data.Length);496 }497 catch (Exception e)498 {499 Fail("failed - exception " + e.ToString());500 }501 502 if (!input.Equals(Hex.ToHexString(data)))503 {504 Fail("failed key generation (768) Test");505 }506 507 genParam = new RsaKeyGenerationParameters(BigInteger.ValueOf(0x11), new SecureRandom(), 1024, 25);508 509 pGen.Init(genParam);510 pair = pGen.GenerateKeyPair();511 512 eng.Init(true, pair.Public);513 514 if (((RsaKeyParameters)pair.Public).Modulus.BitLength < 1024)515 {516 Fail("failed key generation (1024) length test");517 }518 519 try520 {521 data = eng.ProcessBlock(data, 0, data.Length);522 }523 catch (Exception e)524 {525 Fail("failed - exception " + e.ToString());526 }527 528 eng.Init(false, pair.Private);529 530 try531 {532 data = eng.ProcessBlock(data, 0, data.Length);533 }534 catch (Exception e)535 {536 Fail("failed - exception " + e.ToString());537 }538 539 if (!input.Equals(Hex.ToHexString(data)))540 {541 Fail("failed key generation (1024) test");542 }543 544 genParam = new RsaKeyGenerationParameters(545 BigInteger.ValueOf(0x11), new SecureRandom(), 16, 25);546 pGen.Init(genParam);547 548 for (int i = 0; i < 100; ++i)549 {550 pair = pGen.GenerateKeyPair();551 RsaPrivateCrtKeyParameters privKey = (RsaPrivateCrtKeyParameters)pair.Private;552 BigInteger pqDiff = privKey.P.Subtract(privKey.Q).Abs();553 554 if (pqDiff.BitLength < 5)555 {556 Fail("P and Q too close in RSA key pair");557 }558 }559 560 doTestBadSig();561 doTestOaep(pubParameters, privParameters);562 doTestStrictPkcs1Length(pubParameters, privParameters);563 doTestDudPkcs1Block(pubParameters, privParameters);564 doTestMissingDataPkcs1Block(pubParameters, privParameters);565 doTestTruncatedPkcs1Block(pubParameters, privParameters);566 doTestWrongPaddingPkcs1Block(pubParameters, privParameters);567 568 try569 {570 new RsaEngine().ProcessBlock(new byte[] { 1 }, 0, 1);571 Fail("failed initialisation check");572 }573 catch (InvalidOperationException)574 {575 // expected576 }577 }578 579 public static void Main(580 string[] args)581 {582 ITest test = new RsaTest();583 ITestResult result = test.Perform();584 585 Console.WriteLine(result.ToString());586 }587 588 [Test]589 public void TestFunction()590 {591 //Assert.AreEqual(Name + ": Okay", resultText);592 }593 }594 }