在C#中,我正在通过如下操作加密文本数据(请注意,我正在以块(块)形式加密数据):
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)
{
}
}
如你所见,我正在对数据进行块解密。所以我的问题是,我们如何在Java(使用bouncy castle)中进行块式加密(就像我在文章的第一段代码中在.NET中所做的那样)?
这不是一个常见的操作,因为对于大数据(甚至更小的数据),通常使用混合加密,其中使用对称密码的操作模式(例如CBC)来加密较大的数据对象。
据我所知,没有直接的方法从cipher
实例请求RSA/PKCS#1的最大输入大小。
然而,这并不是一个大问题,因为您可以在给定RSA密钥大小的情况下自己计算这个值。并且该密钥大小与模数的大小(以字节为单位)相同:
(keysize-1)/byte.size+1
或者,如果keysize是8的倍数(像往常一样),当然只需keysize/byte.size
;要获得keysize,只需将密钥强制转换为RSAPublickey
,然后调用GetModulus()
,然后在生成的BigInteger
上调用BitLengts()
。
注意,发送没有完整性保护(例如签名)的密文不被认为是非常安全的。PKCS#1也可能成为填充oracle攻击的牺牲品,特别是在传输模式安全中使用时。RSA/OAEP将是一个更好的选择,用于混合加密(因为RSA/OAEP将存储更少)。
我在C#中有一个传递公钥字符串的方法。 我传递的公钥字符串是 我得到一个错误组织。BouncyCastle。安全InvalidKeyException:“不是RSA密钥”。我传递给该方法的公钥格式是否不正确?
在本章中,我们将重点介绍RSA密码加密的不同实现及其所涉及的功能。 您可以引用或包含此python文件以实现RSA密码算法实现。 加密算法包含的模块如下 - from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP from Crypto.Signature import PKCS1_v1_5 from Crypto
我正在检查一个用Python编写的代码,它用来生成一个RSA公钥对。 它会生成keypair,但是在代码的末尾,它会再次运行ssh-keygen。我不知道为什么这样做。因为,rsa.generate()本身将生成keypair,我们将其导出到两个单独的文件中。为什么需要再次运行ssh-keygen? 下面是代码中的几行: 文件pub将存储公钥,id_rsa将存储来自rsa.generate()函数
所以,接下来我需要的是: 创建用于开发的证书,分别为客户端和服务器获取一个证书 通过从客户端编码并在服务器上解码的API检索密码 现在,我按照这个链接创建了certifiactes。那里的女孩一步一步地给出了如何获得自己签名的证书、将其存放在商店等方面的指导。现在,我有问题的部分是: 真的会有人帮我。
问题内容: 我试图来回编码一个简单的String“ test”。 但是,尽管加密工作得很好(ALGORITHM是“ RSA”),但是当尝试解密刚刚从加密“ test”中获得的字符串时,出现以下异常: javax.crypto.IllegalBlockSizeException:数据不得超过256个字节 我是否应该将加密的字节分成256个块才能解密? 问题答案: 您无法可靠地将随机字节转换为。结果将
我们封装了一个RSA 加解密的工具放在 extends 中。首先看看它的文件结构 rsa |-- RSACrypt 加解密主程序 |-- RSACryptBigData 大数据加解密 |-- SignUtil 签名类 |-- rsa_public_key.pem 公钥 |-- rsa_private_key.pem 私钥 RSACrypt API RSAC