项目需要对接Java的接口,一些参数需要用到Rsa加密,经过多次尝试,该工具类可以跟Java的接口正确解析,在此记录一下,后面会附上Java的代码。
C# RSA工具类代码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace Tools
{
public class RSAHelper
{
public static string PubEncrypt1(string pubKey, string src)
{
try
{
using (RSA rsa = RSA.Create())
{
// 导入公钥(PEM 格式或 XML 格式)
//ImportPublicKey(rsa, pubKey);
var pub = pubKey.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "");
rsa.ImportSubjectPublicKeyInfo(Convert.FromBase64String(pub), out _);
byte[] dataToEncrypt = Encoding.UTF8.GetBytes(src);
//int keySize = rsa.KeySize / 8; // in bytes
//int blockSize = keySize - 42; // 最大明文长度(OAEP SHA256)= keySize - 2 * hashLength = 256 - 2*32 = 192
int chunkSize = 117; // Java 示例中使用的是 117 字节,对应 1024 bit 密钥 + SHA-256 OAEP
byte[] encryptedData;
using (var memoryStream = new MemoryStream())
{
int offset = 0;
while (offset < dataToEncrypt.Length)
{
int remaining = dataToEncrypt.Length - offset;
int blockLen = Math.Min(chunkSize, remaining);
byte[] block = new byte[blockLen];
Array.Copy(dataToEncrypt, offset, block, 0, blockLen);
byte[] encryptedBlock = rsa.Encrypt(block, RSAEncryptionPadding.OaepSHA256);
memoryStream.Write(encryptedBlock, 0, encryptedBlock.Length);
offset += blockLen;
}
encryptedData = memoryStream.ToArray();
}
return Convert.ToBase64String(encryptedData);
}
}
catch (Exception ex)
{
Console.WriteLine("加密失败:" + ex.Message);
throw;
}
}
}
}
Java那边的部分代码:
public class Encryption {
private static final int MAX_ENCRYPT_BLOCK = 117;
public static String symEncrypt(String strkey, String src) throws Exception {
String target = null;
try {
Key key = KeysFactory.getSymKey(strkey);
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
IvParameterSpec iv = new IvParameterSpec(strkey.substring(0, 16).getBytes());
cipher.init(1, key, iv);
byte[] encodeResult = cipher.doFinal(src.getBytes(StandardCharsets.UTF_8));
target = Base64Util.encryptBASE64(encodeResult);
return target;
} catch (NoSuchPaddingException | UnsupportedEncodingException | InvalidKeyException | IllegalBlockSizeException
| BadPaddingException | NoSuchAlgorithmException var7) {
Logger.error(var7);
throw new Exception("加密失败" + var7.getMessage());
}
}
public static String pubEncrypt(String pubKey, String src) throws Exception {
String target = null;
ByteArrayOutputStream out = null;
try {
Key key = KeysFactory.getPublicKey(pubKey);
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
cipher.init(1, key,
new OAEPParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA-256"), PSpecified.DEFAULT));
byte[] data = src.getBytes();
int inputLen = data.length;
out = new ByteArrayOutputStream();
int offSet = 0;
for (int i = 0; inputLen - offSet > 0; offSet = i * 117) {
byte[] cache;
if (inputLen - offSet > 117) {
cache = cipher.doFinal(data, offSet, 117);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
++i;
}
target = Base64Util.encryptBASE64(out.toByteArray());
} catch (NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException
| NoSuchAlgorithmException var14) {
Logger.error(var14);
throw new Exception("加密失败" + var14.getMessage());
} finally {
if (out != null) {
out.close();
}
}
return target;
}
}