BouncyCastle.Crypto的RSA算法调用源码
C#的BouncyCastle.Crypto,RSA算法调用的源码,正在研究这个,分享给大家。
官网:http://www.bouncycastle.org/csharp/
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 try 134 { 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 try 147 { 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 decrypt 165 // 166 IAsymmetricBlockCipher eng = new OaepEncoding(new RsaEngine()); 167 byte[] data = Hex.Decode(input); 168 169 eng.Init(true, pubParameters); 170 171 try 172 { 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 try 183 { 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 Java 198 /** 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 try 298 { 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 try 309 { 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 // RAW 331 // 332 IAsymmetricBlockCipher eng = new RsaEngine(); 333 334 eng.Init(true, pubParameters); 335 336 try 337 { 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 try 348 { 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 try 366 { 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 try 377 { 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 decrypt 392 // 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 try 403 { 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 try 414 { 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 decrypt 429 // 430 eng = new Pkcs1Encoding(((Pkcs1Encoding)eng).GetUnderlyingCipher()); 431 432 eng.Init(true, privParameters); 433 434 try 435 { 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 try 446 { 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 test 464 // 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 try 483 { 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 try 494 { 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 try 520 { 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 try 531 { 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 try 569 { 570 new RsaEngine().ProcessBlock(new byte[] { 1 }, 0, 1); 571 Fail("failed initialisation check"); 572 } 573 catch (InvalidOperationException) 574 { 575 // expected 576 } 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 }