本章记录关于Java MD5withRSA加密算法的C#实现。由于C#不提供MD5withRSA的内置实现,所以必须依赖其他的第三方库。这里提供一个简单的sample来演绎[bouncycastle]的加密库。
Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。该算法的文件号为RFC 1321(R.Rivest,MIT Laboratory for Computer Science and RSA Data Security Inc. April 1992)。–来自百度百科
RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。–来自百度百科
如果你在百度上搜索 MD5withRSA 恐怕搜到最多的就是关于支付的。对的,这个加密算法常用与支付阶段。主要用途是防篡改。一般来说传递明文 可能被黑客从传输阶段拦截,篡改,此时我们用私钥将MD5加密后的密文再加密与明文一起发送。服务器用公匙将密文解密此时得到md5的密文,然后将明文用md5加密得到密文,匹配这两个密文。如果一致则消息是未被篡改的。
Current feature list:
Generation and parsing of PKCS-12 files.X.509: Generators and parsers for V1 and V3 certificates, V2 CRLs and attribute certificates.PBE algorithms supported by PbeUtilities: PBEwithMD2andDES-CBC, PBEwithMD2andRC2-CBC, PBEwithMD5andDES-CBC, PBEwithMD5andRC2-CBC, PBEwithSHA1andDES-CBC, PBEwithSHA1andRC2-CBC, PBEwithSHA-1and128bitRC4, PBEwithSHA-1and40bitRC4, PBEwithSHA-1and3-keyDESEDE-CBC, PBEwithSHA-1and2-keyDESEDE-CBC, PBEwithSHA-1and128bitRC2-CBC, PBEwithSHA-1and40bitRC2-CBC, PBEwithHmacSHA-1, PBEwithHmacSHA-224, PBEwithHmacSHA-256, PBEwithHmacRIPEMD128, PBEwithHmacRIPEMD160, and PBEwithHmacRIPEMD256.Signature algorithms supported by SignerUtilities: MD2withRSA, MD4withRSA, MD5withRSA, RIPEMD128withRSA, RIPEMD160withECDSA, RIPEMD160withRSA, RIPEMD256withRSA, SHA-1withRSA, SHA-224withRSA, SHA-256withRSAandMGF1, SHA-384withRSAandMGF1, SHA-512withRSAandMGF1, SHA-1withDSA, and SHA-1withECDSA.Symmetric key algorithms: AES, Blowfish, Camellia, CAST5, CAST6, ChaCha, DES, DESede, GOST28147, HC-128, HC-256, IDEA, ISAAC, Noekeon, RC2, RC4, RC5-32, RC5-64, RC6, Rijndael, Salsa20, SEED, Serpent, Skipjack, TEA/XTEA, Threefish, Tnepres, Twofish, VMPC and XSalsa20.Symmetric key modes: CBC, CFB, CTS, GOFB, OFB, OpenPGPCFB, and SIC (or CTR).Symmetric key paddings: ISO10126d2, ISO7816d4, PKCS-5/7, TBC, X.923, and Zero Byte.Asymmetric key algorithms: ElGamal, DSA, ECDSA, NaccacheStern and RSA (with blinding).Asymmetric key paddings/encodings: ISO9796d1, OAEP, and PKCS-1.AEAD block cipher modes: CCM, EAX, GCM and OCB.Digests: GOST3411, Keccak, MD2, MD4, MD5, RIPEMD128, RIPEMD160, RIPEMD256, RIPEMD320, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SHA3, Tiger, and Whirlpool.XOFs: SHAKE.Signer mechanisms: DSA, ECDSA, ECGOST3410, ECNR, GOST3410, ISO9796d2, PSS, RSA, X9.31-1998.Key Agreement: Diffie-Hellman, EC-DH, EC-MQV, J-PAKE, SRP-6a.Macs: CBCBlockCipher, CFBBlockCipher, CMAC, GMAC, GOST28147, HMac, ISO9797 Alg. 3, Poly1305, SipHash, SkeinMac, VMPCMAC.PBE generators: PKCS-12, and PKCS-5 - schemes 1 and 2.OpenPGP (RFC 4880)Cryptographic Message Syntax (CMS, RFC 3852), including streaming API.Online Certificate Status Protocol (OCSP, RFC 2560).Time Stamp Protocol (TSP, RFC 3161).TLS/DTLS client/server up to version 1.2, with support for the most common ciphersuites and extensions, and many less common ones. Non-blocking API available.Elliptic Curve Cryptography: support for generic F2m and Fp curves, high-performance custom implementations for many standardized curves.Reading/writing of PEM files, including RSA and DSA keys, with a variety of encryptions.PKIX certificate path validation
/// <summary>
/// MD5withRSA Signing
/// https://www.vrast.cn
/// keyle_xiao 2017.1.12
/// </summary>
public class MD5withRSASigning
{
public Encoding encoding = Encoding.UTF8;
public string SignerSymbol = "MD5withRSA";
public MD5withRSASigning() { }
public MD5withRSASigning(Encoding e, string s)
{
encoding = e;
SignerSymbol = s;
}
private AsymmetricKeyParameter CreateKEY(bool isPrivate, string key)
{
byte[] keyInfoByte = Convert.FromBase64String(key);
if (isPrivate)
return PrivateKeyFactory.CreateKey(keyInfoByte);
else
return PublicKeyFactory.CreateKey(keyInfoByte);
}
public string Sign(string content, string privatekey)
{
ISigner sig = SignerUtilities.GetSigner(SignerSymbol);
sig.Init(true, CreateKEY(true, privatekey));
var bytes = encoding.GetBytes(content);
sig.BlockUpdate(bytes, 0, bytes.Length);
byte[] signature = sig.GenerateSignature();
/* Base 64 encode the sig so its 8-bit clean */
var signedString = Convert.ToBase64String(signature);
return signedString;
}
public bool Verify(string content, string signData, string publickey)
{
ISigner signer = SignerUtilities.GetSigner(SignerSymbol);
signer.Init(false, CreateKEY(false, publickey));
var expectedSig = Convert.FromBase64String(signData);
/* Get the bytes to be signed from the string */
var msgBytes = encoding.GetBytes(content);
/* Calculate the signature and see if it matches */
signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
return signer.VerifySignature(expectedSig);
}
}