当前位置: 首页 > 面试题库 >

Java BC SicBlockCipher直接输出等效于C#

陶鸿畴
2023-03-14
问题内容

我正在用C#实现某种东西,为此我有一个单独的规范并且对我需要做的事情有很清楚的了解,但是与此同时,我有一个Java实现,并且希望在这种情况下遵循Java实现,例如尽我所能。

该代码涉及一个加密流,并且Java源代码在这里 。相关行在这里:

  private final StreamCipher enc;
...
  BlockCipher cipher;
  enc = new SICBlockCipher(cipher = new AESEngine());
  enc.init(true, new ParametersWithIV(new KeyParameter(secrets.aes), new byte[cipher.getBlockSize()]));
...
...
byte[] ptype = RLP.encodeInt((int) frame.type); //Result can be a single byte long
...
...
enc.processBytes(ptype, 0, ptype.length, buff, 0);
out.write(buff, 0, ptype.length); //encrypt and write a single byte from the SICBlockCipher stream

上面的Java BouncyCastle SicBlockCipher是a StreamCipher,允许处理少于Aes块大小的单个或少量字节。

在c#BouncyCastle中,SicBlockCipher唯一提供的ProcessBlock和BufferedBlockCipher似乎没有提供使用ProcessBytes保证输出的方法。

我需要使用C#BouncyCastle库来实现等效功能吗?


问题答案:

不幸的是,SicBlockCipher它本身并未实现为流密码,因此(实际上)不能直接使用此功能。

BufferedBlockCipher创建时要考虑许多不同的操作模式。它缓冲 输入
,而对于实现的计数器(CTR)模式,则SicBlockCipher需要缓冲加密的计数器块。

加密的计数器块构成密钥流,然后可以将其与明文进行XOR运算以创建密文流(或者,实际上,使用密文再次检索明文,加密是针对计数器模式的解密)。

我看到如何执行此操作的唯一方法是创建自己的实现IBlockCipher并实现所述功能。

这是计数器模式作为流密码…

using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Modes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SicStream
{
    public class SicStreamCipher : IStreamCipher
    {
        private SicBlockCipher parent;
        private int blockSize;

        private byte[] zeroBlock;

        private byte[] blockBuffer;
        private int processed;

        public SicStreamCipher(SicBlockCipher parent)
        {
            this.parent = parent;
            this.blockSize = parent.GetBlockSize();

            this.zeroBlock = new byte[blockSize];

            this.blockBuffer = new byte[blockSize];
            // indicates that no bytes are available: lazy generation of counter blocks (they may not be needed)
            this.processed = blockSize;
        }

        public string AlgorithmName
        {
            get
            {
                return parent.AlgorithmName;
            }
        }

        public void Init(bool forEncryption, ICipherParameters parameters)
        {
            parent.Init(forEncryption, parameters);

            Array.Clear(blockBuffer, 0, blockBuffer.Length);
            processed = blockSize;
        }

        public void ProcessBytes(byte[] input, int inOff, int length, byte[] output, int outOff)
        {
            int inputProcessed = 0;
            while (inputProcessed < length)
            {
                // NOTE can be optimized further
                // the number of available bytes can be pre-calculated; too much branching
                if (processed == blockSize)
                {
                    // lazilly create a new block of key stream
                    parent.ProcessBlock(zeroBlock, 0, blockBuffer, 0);
                    processed = 0;
                }

                output[outOff + inputProcessed] = (byte)(input[inOff + inputProcessed] ^ blockBuffer[processed]);

                processed++;
                inputProcessed++;
            }
        }

        public void Reset()
        {
            parent.Reset();

            Array.Clear(blockBuffer, 0, blockBuffer.Length);
            this.processed = blockSize;
        }

        public byte ReturnByte(byte input)
        {
            if (processed == blockSize)
            {
                // lazily create a new block of key stream
                parent.ProcessBlock(zeroBlock, 0, blockBuffer, 0);
                processed = 0;
            }
            return (byte)(input ^ blockBuffer[processed++]);
        }
    }
}

…并且在此处进行了包装,以便可以在使用分组密码操作模式的代码中对其进行改装…

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Modes;

namespace SicStream
{
    /**
     * A class that implements an online Sic (segmented integer counter mode, or just counter (CTR) mode for short).
     * This class buffers one encrypted counter (representing the key stream) at a time.
     * The encryption of the counter is only performed when required, so that no key stream blocks are generated while they are not required.
     */
    public class StreamingSicBlockCipher : BufferedCipherBase
    {
        private SicStreamCipher parent;
        private int blockSize;

        public StreamingSicBlockCipher(SicBlockCipher parent)
        {
            this.parent = new SicStreamCipher(parent);
            this.blockSize = parent.GetBlockSize();
        }

        public override string AlgorithmName
        {
            get
            {
                return parent.AlgorithmName;
            }
        }

        public override byte[] DoFinal()
        {
            // returns no bytes at all, as there is no input
            return new byte[0];
        }

        public override byte[] DoFinal(byte[] input, int inOff, int length)
        {
            byte[] result = ProcessBytes(input, inOff, length);

            Reset();

            return result;
        }

        public override int GetBlockSize()
        {
            return blockSize;
        }

        public override int GetOutputSize(int inputLen)
        {
            return inputLen;
        }

        public override int GetUpdateOutputSize(int inputLen)
        {
            return inputLen;
        }

        public override void Init(bool forEncryption, ICipherParameters parameters)
        {
            parent.Init(forEncryption, parameters);
        }

        public override byte[] ProcessByte(byte input)
        {
            return new byte[] { parent.ReturnByte(input) };
        }

        public override byte[] ProcessBytes(byte[] input, int inOff, int length)
        {
            byte[] result = new byte[length];
            parent.ProcessBytes(input, inOff, length, result, 0);
            return result;
        }

        public override void Reset()
        {
            parent.Reset();
        }
    }
}

请注意,由于需要创建其他数组,因此最后一个代码效率较低。



 类似资料:
  • 问题内容: 我正在从xml配置转移到注释。我想转换一个会话范围的bean是 可以通过注释完成此操作吗?如果没有,我该怎么做才能使该声明继续工作? 问题答案: 在spring上下文xml中,执行以下操作: 请注意,尽管如此,你将需要为该包中的所有类编写接口。

  • 在为一些日期助手编写单元测试时,我偶然发现了的特定行为,我想了解如何解决这个问题。 输出年份时 现在文档说明了年份模式: 如果字母数少于四个(但不是两个),则符号仅按符号样式输出负年份。正常。否则,如果超出焊盘宽度,则根据SignStyle输出符号。超过PAD。 这给了我一个提示,但我仍然不知道: 如何使输出完全相同的字符串为Y10K日期,在我的例子(=无符号的正年份

  • 问题内容: 我正在开发Java程序,我确实需要能够以一定的频率和持续时间播放声音,类似于c#方法System.Beep,我知道如何在C#中使用它,但是我找不到用Java做到这一点的一种方法。是否有等效的方法或另一种方法? 问题答案: 我认为没有办法在便携式2 Java 中用“哔”声播放音乐1。您将需要使用我认为的API …除非找到可以为您简化事情的第三方库。 如果您想走这条路,那么此页面可能会给您

  • 问题内容: 我是一名普通的C#开发人员,但有时我会使用Java开发应用程序。我想知道是否有Java等效于C#async / await?简单来说,java相当于什么: 问题答案: 不,在Java中-甚至在v5之前的C#中,都没有等效的异步/等待方式。 在后台构建状态机是一项相当复杂的语言功能。 Java中对异步/并发的 语言 支持相对较少,但是该软件包包含许多与此相关的有用 类 。(不完全等同于任

  • 问题内容: 该表示法是: 实际上不哈希对象;它实际上只是转换为字符串(通过它是一个对象,还是其他各种原始类型的内置转换),然后在“ ”中查找该字符串,而不对其进行哈希处理。也不会检查对象是否相等-如果两个不同的对象具有相同的字符串转换,则它们将彼此覆盖。 鉴于此-在JavaScript中是否有任何有效的hashmap实现?(例如,第二个Google结果产生的实现对任何操作都是O(n)。其他各种结果

  • 问题内容: 我正在尝试从Swift的iTu​​nesU中的“开发适用于iPhone和iPad的ios7应用程序”中复制斯坦福Matchismo游戏。 在第3讲幻灯片的第77页上,它显示了使用,这不是Swift上的选项。Swift文档示例显示了一个具有数组的示例,但是我不知道如何使Interface Builder将多个插座连接到同一个/ Array。 有人知道如何做到这一点吗? 我知道我可以创建1