gpt4 book ai didi

java - 在 java 中使用 Bouncy CaSTLe 进行 block 式 RSA 加密

转载 作者:行者123 更新时间:2023-11-30 10:29:59 28 4
gpt4 key购买 nike

在 C# 中,我通过执行以下操作来加密文本数据(请注意我正在以 block ( block )的形式加密数据):

        public string EncryptData(string publicKey, string data)
{
try
{
var bytesToEncrypt = Encoding.UTF8.GetBytes(data);
int srclen = bytesToEncrypt.Length;

//Prepare encryption engine
var encryptEngine = new Pkcs1Encoding(new RsaEngine());

//Initialize Key
using (var txtreader = new StringReader(publicKey))
{
var keyParameter = (AsymmetricKeyParameter)new PemReader(txtreader).ReadObject();
encryptEngine.Init(true, keyParameter);
}

//Encrypt in loop
byte[] complete = new byte[0];
int src_block_size = encryptEngine.GetInputBlockSize();
for (int idx = 0; idx < srclen; idx += src_block_size)
{
int data_len = srclen - idx;
if (data_len > src_block_size)
{
data_len = src_block_size;
}

var encryptedChunk = encryptEngine.ProcessBlock(bytesToEncrypt, idx, data_len);
complete = CombineByteArrays(complete, encryptedChunk);
}

var finalString = Convert.ToBase64String(complete);
return finalString;
}
catch (InvalidCipherTextException)
{
//catch exception
}
}

现在,我需要为某些 java 人员(我一点也不熟悉 java)提供相同的加密逻辑。现在他们是这样做的:

public static byte[] encrypt(byte[] text, PublicKey key) throws Exception
{
byte[] cipherText = null;
//
// get an RSA cipher object and print the provider
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

// encrypt the plain text using the public key
cipher.init(Cipher.ENCRYPT_MODE, key);
cipherText = cipher.doFinal(text);
return cipherText;
}

因此,有时解密(发生在基于 .Net 的服务器上)会失败并出现错误“输入对于 RSA 密码而言太大”。所以我怀疑这可能是因为加密和解密数据的逻辑不同(加密发生在基于 java 的客户端上,逻辑在上面,解密发生在基于 .Net 的客户端上,逻辑如下):

public string DecryptData(string privateKey, string base64Data)
{
try
{
var bytesToDecrypt = Convert.FromBase64String(base64Data);
AsymmetricCipherKeyPair keyPair;
//var internalEngine = new RsaEngine();
var decryptEngine = new RsaEngine(); //No paddind. We'll hunt the data inside packets
using (var txtreader = new StringReader(privateKey))
{
keyPair = (AsymmetricCipherKeyPair)new PemReader(txtreader).ReadObject();
decryptEngine.Init(false, keyPair.Private);
}

//Loop por todo el bloque y saca data
byte[] complete = new byte[0];
int blockSize = decryptEngine.GetInputBlockSize();
for (int chunkPosition = 0; chunkPosition < bytesToDecrypt.Length; chunkPosition += blockSize)
{
//int chunkSize = Math.Min(blockSize, bytesToDecrypt.Length - ((chunkPosition / blockSize) * blockSize));
int chunkSize = bytesToDecrypt.Length - chunkPosition;
if (chunkSize > blockSize)
{
chunkSize = blockSize;
}

var decryptedChunk = decryptEngine.ProcessBlock(bytesToDecrypt, chunkPosition, chunkSize);

//the actual decrypted data is in the middle, locate it!
int idxFirstZero = -1;
int outlen = decryptedChunk.Length;
int idxNextZero = (int)outlen;
for (int i = 0; i < outlen; i++)
{
if (decryptedChunk[i] == 0)
{
if (idxFirstZero < 0)
{
idxFirstZero = i;
}
else
{
idxNextZero = i;
break;
}
}
}

var totalSizeToCopy = idxNextZero - idxFirstZero - 1;
Array.Resize(ref complete, complete.Length + totalSizeToCopy);
int dstOffset = complete.Length - totalSizeToCopy > 0 ? complete.Length - totalSizeToCopy : 0;
Buffer.BlockCopy(decryptedChunk, idxFirstZero + 1, complete, dstOffset, totalSizeToCopy);
}

var finalString = Encoding.UTF8.GetString(complete).Trim('\0');
return finalString;
}
catch (InvalidCipherTextException)
{

}
}

如您所见,我正在以 block 的形式解密数据。所以我的问题是我们如何在 java 中(使用充气城堡)逐 block 进行加密(就像我在博文的第一个代码片段中在 .Net 中所做的那样)?

最佳答案

这不是一个常见的操作,因为对于大数据(甚至更小的数据)通常使用混合加密,其中使用对称密码的操作模式(例如 CBC)来加密更大的数据对象。

据我所知,没有直接的方法可以从 Cipher 实例请求 RSA/PKCS#1 的最大输入大小。

但是,这不是什么大问题,因为您可以根据 RSA key 大小自行计算。并且此 key 大小与模数的大小(以字节为单位)相同:

  1. 以字节为单位计算模数大小:(keysize - 1)/Byte.SIZE + 1 或者,如果 keysize 是 8 的倍数(像往常一样),只需 keysize/Byte .SIZE 当然是;
  2. 从结果中减去 11 个字节(对于 PKCS#1 v1.5 填充);

要获取 key 大小,只需将您的 key 转换为 RSAPublicKey,然后调用 getModulus(),然后调用 bitLength()结果 BigInteger


请注意,发送没有完整性保护(例如签名)的密文被认为不是很安全。 PKCS#1 也可能成为填充 oracle 攻击的受害者,尤其是在传输模式安全性中使用时。 RSA/OAEP 将是更好的选择,用于混合加密(如 RSA/OAEP will store even less )。

关于java - 在 java 中使用 Bouncy CaSTLe 进行 block 式 RSA 加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43798966/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com