I like to understand if there are any APIs available in lextm sharpsnmp library to encode SNMPv1/v2c/V3 PDU to byte array and also API to construct a SnmpPdu (SNMP v1/v2c/v3) based on a byte array.
Thank you in Advance
To get the raw bytes of a PDU, use ISnmpMessage.ToBytes:
GetRequestMessage getRequest = new(requestID, VersionCode.V1, new OctetString("public"), new Variable[] { variable });
byte[] getRequestBytes = getRequest.ToBytes();
To build a PDU from raw bytes, use MessageFactory.ParseMessages:
byte[] rawBytes = { 0x30, byte2, byte3, ... };
IList<ISnmpMessage> message = MessageFactory.ParseMessages(rawBytes, new UserRegistry());
Related
I want to decrypt fmp4 segment.
This segment was encrypt with HLS Apple Tools (https://developer.apple.com/documentation/http_live_streaming/about_apple_s_http_live_streaming_tools)
METHOD is AES-128
IV is 1d48fc5dee84b5a3e9a428f055e03c2e
I have a key and IV (you can got the key, and segment in google drive https://drive.google.com/drive/folders/1xF-C9EXFvT8qjI--sBB6QMPn8cNW7L-D?usp=sharing)
To decrypt I use Poco library.
This is my code:
Poco::Crypto::Cipher::ByteVec readKey(const std::string& uri) {
Poco::Crypto::Cipher::ByteVec key;
auto stream = Stream::makeStream(uri);
if (stream->open(uri, {})) {
key.resize(KEY_SIZE);
stream->read((char*)&key[0], KEY_SIZE);
}
return key;
}
std::vector<uint8_t> _key = readKey("./unit-tests/resources/cipher-stream/file.key");
std::string ivSrc = "1d48fc5dee84b5a3e9a428f055e03c2e";
Poco::Crypto::Cipher::ByteVec iv {ivSrc.begin(), ivSrc.end()};
Poco::Crypto::CipherKey key("aes-128-cbc", _key, iv);
Poco::Crypto::Cipher::Ptr cipher = Poco::Crypto::CipherFactory::defaultFactory().createCipher(key);
Poco::FileInputStream src("./unit-tests/resources/cipher-stream/fileSequence1.m4s");
Poco::FileOutputStream dst("./unit-tests/resources/cipher-stream/fileSequence1_dec.m4s");
Poco::Crypto::CryptoOutputStream decryptor(dst, cipher->createDecryptor());
Poco::StreamCopier::copyStream(src, decryptor);
// decryptor.close();
src.close();
dst.close();
Problem description:
After decryption I got distorted data. You can see this at the beginning of the file. Please see picture below. On the right side of the image file is distorted.
The correct data you can see on the left side.
You're using the wrong IV; that will lead to the first block (16 bytes) being corrupted. Your IV hex value is 1d48fc5dee84b5a3e9a428f055e03c2e, but you're interpreting that as ASCII. It's using the first 16 bytes of your string and ignoring the rest.
I haven't used Poco in a long time and don't remember if there's a hex parser handy, but that's what you need. Or write the IV directly in hex rather than as an ASCII string.
I have a TCP Client in rust, which should communicate with a Java Server. I got the basics working and can send bytearrays between them.
But for the bytearray buffer, I need to know the length of the bytearray. But I don't know I should obtain it. At the moment, I only have a fixed size for the buffer right now.
My Rust code looks like this:
loop {
let mut buffer = vec![0; 12]; //fixed buffer length
let n = stream.read(&mut buffer).await;
let text = from_utf8(&buffer).unwrap();
println!("{}", text);
}
In Java, you can send the size of the buffer directly as an Integer with DataInputStream. Is there any option to do that in rust?
For example, this is how I'm doing it in Java:
public String readMsg(Socket socket) throws IOException {
DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
byte[] bytes = new byte[in.readInt()]; //dynamic buffer length
in.readFully(bytes);
return new String(bytes, StandardCharsets.US_ASCII);
}
What you want to know is a property of the protocol that you are using. It's not a property of the programming language you use. Based on your Java code it seems like you are using a protocol which sends a 4 byte length field before the message data (signed/unsigned?).
If that is the case you can handle reading the message the same way in Rust:
1. Read the 4 bytes in order to obtain the length information
2. Read the remaining data
3. Deserialize the data
fn read_message(stream: Read) -> io::Result<String> {
let mut buffer = [0u8; 4];
// Read the length information
stream.read_exact(&mut buffer[..])?;
// Deserialize the length
let size = u32::from_be_bytes(buffer);
// Allocate a buffer for the message
// Be sure to check against a maximum size before doing this in production
let mut payload = vec![0; size];
stream.read_exact(&mut payload[..]).await;
// Convert the buffer into a string
let text = String::from_utf8(payload).map_err(/* omitted */)?;
println!("{}", text);
Ok(text)
}
This obviously is only correct if your protocol uses length prefixed messages with a 4byte unsigned int prefix. This is something that you need to check.
I have a binary data stream which contains data that should be interpreted as a Qstring. Starting from the third byte. Here is how the package is generated (on a client).
QByteArray package;
package.append( QByteArray::fromHex("0002") ); // First two bytes
package.append( "filename.txt" ); // String of undefined size
package.append( QByteArray::fromHex("00")); // End of string
The decoding is done on a different machine (server). I would like to get a Qstring of value "filename.txt" from the QByteArray package without relying on the size of the string (since the server doesn't have that information) but on the string terminator 00. How can this be achieved?
Since this decoding will be done on a different machine, how should the raw data be generated on the client to avoid problems with endianess?
You should wrap the QByteArray in a QDataStream so you can specify the endianess explicitly and make use of the stream operators
QByteArray package;
QDataStream stream(package, QIODevice::WriteOnly);
stream.setByteOrder( QDataStream::BigEndian);
stream << static_cast<quint16>(0x0002); // First two bytes
stream << "filename.txt"; // String of undefined size
// no need to write terminating 0 because data stream will prepend length
then you can read in the other direction:
QByteArray package;
QDataStream stream(package, QIODevice::WriteOnly);
stream.setByteOrder( QDataStream::BigEndian);
quint16 id;
stream >> id; // First two bytes
char* filename;
stream >> filename; // String of undefined size
QString file = QString.fromLatin1(filename);
delete[] filename; //cleanup
or you can pass a QString to the stream in the first place and not need to deal with the char array:
QByteArray package;
QDataStream stream(package, QIODevice::WriteOnly);
stream.setByteOrder( QDataStream::BigEndian);
stream << static_cast<quint16>(0x0002); // First two bytes
stream << QStringLiteral("filename.txt"); // String of undefined size
note that this will write in utf16 meaning it is unicode enabled
the serialization format is documented at http://qt-project.org/doc/qt-5.0/qtcore/datastreamformat.html
Using .NET 4.0, IIS 7.5 (Windows Server 2008 R2). I would like to stream out a binary content of about 10 MB. The content is already in a MemoryStream. I wonder if IIS7 automatically chunks the output stream. From the client receiving the stream, is there any difference between these two approaches:
//#1: Output the entire stream in 1 single chunks
Response.OutputStream.Write(memoryStr.ToArray(), 0, (int) memoryStr.Length);
Response.Flush();
//#2: Output by 4K chunks
byte[] buffer = new byte[4096];
int byteReadCount;
while ((byteReadCount = memoryStr.Read(buffer, 0, buffer.Length)) > 0)
{
Response.OutputStream.Write(buffer, 0, byteReadCount);
Response.Flush();
}
Thanks in advance for any help.
I didn't try your 2nd suggestion passing the original data stream. The memory stream was indeed populated from a Response Stream of a Web Request. Here is the code,
HttpWebRequest webreq = (HttpWebRequest) WebRequest.Create(this._targetUri);
using (HttpWebResponse httpResponse = (HttpWebResponse)webreq.GetResponse())
{
using (Stream responseStream = httpResponse.GetResponseStream())
{
byte[] buffer = new byte[4096];
int byteReadCount = 0;
MemoryStream memoryStr = new MemoryStream(4096);
while ((byteReadCount = responseStream.Read(buffer, 0, buffer.Length)) > 0)
{
memoryStr.Write(buffer, 0, byteReadCount);
}
// ... etc ... //
}
}
Do you think it can safely pass the responseStream to Response.OutputStream.Write() ? If yes, can you suggest an economic way of doing so? How to send ByteArray + exact stream length to Response.OutputStream.Write()?
The second option is the best one as ToArray will in fact create a copy of the internal array stored in the MemoryStream.
But, you can also preferably use memoryStr.GetBuffer() that will return a reference to this internal array. In this case, you need to use the memoryStr.Length property because the buffer returned by GetBuffer() is in general bigger than the stored actual data (it's allocated chunk by chunk, not byte by byte).
Note that it would be best to pass the original data as a stream directly to the ASP.NET outputstream, instead of using an intermediary MemoryStream. It depends on how you get your binary data in the first place.
Another option, if you serve the exact same content often, is to save this MemoryStream to a physical file (using a FileStream), and use Response.TransmitFile on all subsequent requests. Response.TransmitFile is using low level Windows socket layers and there's nothing faster to send a file.
Can someone shed some lights on how to convert ByteArray into int?
Thanks,
So to get a flavor of doing this, you can try this bit of code:
function test(){
var bytes:ByteArray = new ByteArray();
bytes.writeInt(0x00DDAA99); //create my byte array with int 14527129
bytes.position = 0; //move the postion to the start
var newInt:int = bytes.readInt(); //read the bytes from starting position
trace("new num: "+newInt); //print out the number
}
This code will first create a byte array and put an int into it. This is presumably where you need your code to start. This then makes the assumption that there are 4 bytes to read after the starting position which I have set to 0. It then reads the 4 bytes off the byte array into the queue. Note that if you do not have 4 bytes in your ByteArray or your position is not set correctly, your code will fail. Make sure you add the checks for those scenarios.
This code also assumes that the byte array is Big Endian. Make sure that if you have a byte array from another system, that you know which endian-ness the int value has. Change the endian value on your byte array if needed.