Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java中使用Bouncy Castle的分块RSA加密_Java_C#_Cryptography_Rsa_Bouncycastle - Fatal编程技术网

java中使用Bouncy Castle的分块RSA加密

java中使用Bouncy Castle的分块RSA加密,java,c#,cryptography,rsa,bouncycastle,Java,C#,Cryptography,Rsa,Bouncycastle,在C#中,我通过执行以下操作来加密文本数据(请注意,我是以块(blocks)的形式加密数据): 因此,有时解密(发生在基于.Net的服务器上)会出现错误“输入太大,无法使用RSA密码”。因此我怀疑这可能是因为加密和解密数据的逻辑不同(加密发生在基于java的客户端上,逻辑如上所述,解密发生在基于.Net的客户端上,逻辑如下): 公共字符串解密数据(字符串私钥、字符串base64数据) { 尝试 { var bytesToDecrypt=Convert.FromBase64String(base6

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

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

公共字符串解密数据(字符串私钥、字符串base64数据)
{
尝试
{
var bytesToDecrypt=Convert.FromBase64String(base64Data);
非对称密码密钥对;
//var internalEngine=新的RsaEngine();
var decryptEngine=new RsaEngine();//无paddind。我们将查找数据包中的数据
使用(var txtreader=newstringreader(privateKey))
{
keyPair=(AsymmetricipherKeyPair)新的PemReader(txtreader).ReadObject();
decryptEngine.Init(false,keyPair.Private);
}
//循环por todo el bloque y saca数据
字节[]完成=新字节[0];
int blockSize=decryptEngine.GetInputBlockSize();
for(int-chunkPosition=0;chunkPositionblockSize)
{
chunkSize=块大小;
}
var decryptedChunk=decryptEngine.ProcessBlock(bytesToDecrypt、chunkPosition、chunkSize);
//实际解密的数据在中间,找到它!
int idxFirstZero=-1;
int-outlen=decryptedChunk.Length;
int idxNextZero=(int)outlen;
for(int i=0;i0?complete.Length-totalSizeToCopy:0;
BlockCopy(decryptedChunk、idxFirstZero+1、complete、DSTFostate、totalSizeToCopy);
}
var finalString=Encoding.UTF8.GetString(complete.Trim)('\0');
返回最后一环;
}
捕获(InvalidCipherTextException)
{
}
}

正如你所看到的,我正在对数据进行分块解密。所以我的问题是,我们如何用java(使用bouncy castle)进行分块加密(就像我在文章的第一个代码片段中在.Net中所做的那样)?

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

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

但是,这不是什么大问题,因为您可以在给定RSA密钥大小的情况下自行计算。并且该密钥大小与模的大小相同(以字节为单位):

  • 以字节为单位计算模数大小:
    (keysize-1)/Byte.size+1
    或者,如果keysize是8的倍数(通常),当然只需
    keysize/Byte.size
  • 从结果中减去11个字节(对于PKCS#1 v1.5填充)
  • 要获得密钥大小,只需将密钥强制转换为
    RSAPublicKey
    ,然后调用
    getmodule()
    ,然后对生成的
    BigInteger
    调用
    bitLength()



    请注意,在没有完整性保护(例如签名)的情况下发送密文并不十分安全。PKCS#1也可能成为填充oracle攻击的受害者,特别是在传输模式安全中使用时。RSA/OAEP将是更好的选择,用于混合加密(如RSA/OAEP).

    这应该是一个学习练习吗?如果不是,请扔掉您的代码并正确实现。RSA不应该用作分组密码。您应该使用AES加密您的邮件,并使用RSA加密随机AES密钥。“…我正在[使用RSA]分块(块)加密数据。”-如果对每个区块应用RSA,则称为ECB模式下的RSA操作。特别警告不要使用这种做法。
            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
                }
            }
    
    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;
        }
    
    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)
                {
    
                }
            }