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