private void DoTest1000000() { byte[] plain = Hex.Decode("0123456789abcdeffedcba9876543210"); byte[] key = Hex.Decode("0123456789abcdeffedcba9876543210"); byte[] cipher = Hex.Decode("595298c7c6fd271f0402f804c33d3f66"); byte[] buf = new byte[16]; IBlockCipher engine = new SM4Engine(); engine.Init(true, new KeyParameter(key)); Array.Copy(plain, 0, buf, 0, buf.Length); for (int i = 0; i != 1000000; i++) { engine.ProcessBlock(buf, 0, buf, 0); } if (!AreEqual(cipher, buf)) { Fail("1000000 encryption test failed"); } engine.Init(false, new KeyParameter(key)); for (int i = 0; i != 1000000; i++) { engine.ProcessBlock(buf, 0, buf, 0); } if (!AreEqual(plain, buf)) { Fail("1000000 decryption test failed"); } }
/** * CBC模式解密数据 * @param cipher 密文数据 * @param key 密钥 * @param iv 向量 * @param isPadding 填充模式,具体支持请看类的常量字段,若使用不支持的模式则会默认无填充 * @return 返回明文字节数据 */ public static byte[] DecryptCBC(byte[] cipher, byte[] key, byte[] iv, int paddingMode) { IBlockCipher engine = new SM4Engine(); engine.Init(false, new KeyParameter(key)); int length = cipher.Length; byte[] plain = new byte[cipher.Length]; iv = (byte [])iv.Clone(); for (int i = 0; length > 0; length -= 16, i += 16) { engine.ProcessBlock(cipher, i, plain, i); for (int j = 0; j < 16; j++) { plain[j + i] = ((byte)(plain[i + j] ^ iv[j])); } Buffer.BlockCopy(cipher, i, iv, 0, 16); } byte[] res = null; if (paddingMode == SM4_PKCS8PADDING) { res = padding(plain, SM4_DECRYPT); } else { res = plain; } return(res); }
/** * CBC模式加密数据 * @param data 待加密数据 * @param key 密钥 * @param iv 向量 * @param paddingMode 填充模式,具体支持请看类的常量字段,若使用不支持的模式则会默认无填充 * @return 返回密文值 */ public static byte[] EncryptCBC(byte[] data, byte[] key, byte[] iv, int paddingMode) { IBlockCipher engine = new SM4Engine(); engine.Init(true, new KeyParameter(key)); if (paddingMode == SM4_PKCS8PADDING) { data = padding(data, SM4_ENCRYPT); } else { data = (byte [])data.Clone(); } int length = data.Length; iv = (byte [])iv.Clone(); for (int i = 0; length > 0; length -= 16, i += 16) { for (int j = 0; j < 16; j++) { data[i + j] = ((byte)(data[i + j] ^ iv[j])); } engine.ProcessBlock(data, i, data, i); Buffer.BlockCopy(data, i, iv, 0, 16); } return(data); }
/** * sm4 ecb模式加密数据 * @param data 待加密数据 * @param key sm4密钥 * @param paddingMode 填充模式,具体支持请看类的常量字段,若使用不支持的模式则会默认无填充 * @return 返回密文数据 */ public static byte[] EncryptECB(byte[] data, byte[] key, int paddingMode) { IBlockCipher engine = new SM4Engine(); engine.Init(true, new KeyParameter(key)); if (paddingMode == SM4_PKCS8PADDING) { data = padding(data, SM4_ENCRYPT); } else { data = (byte [])data.Clone(); } int length = data.Length; for (int i = 0; length > 0; length -= 16, i += 16) { engine.ProcessBlock(data, i, data, i); } return(data); }
/** * sm4 ecb模式解密数据 * @param cipher 密文数据 * @param key sm4密钥 * @param paddingMode 填充模式,具体支持请看类的常量字段,若使用不支持的模式则会默认无填充 * @return 返回明文字节数据 */ public static byte[] DecryptECB(byte[] cipher, byte[] key, int paddingMode) { IBlockCipher engine = new SM4Engine(); engine.Init(false, new KeyParameter(key)); int length = cipher.Length; byte[] tmp = new byte[cipher.Length]; for (int i = 0; length > 0; length -= 16, i += 16) { engine.ProcessBlock(cipher, i, tmp, i); } byte[] plain = null; if (paddingMode == SM4_PKCS8PADDING) { plain = padding(tmp, SM4_DECRYPT); } else { plain = tmp; } return(plain); }