我尝试解密字节,但我在行length of data to decrypt is invalid
read = cryptoStream.Read(buffer, 0, len);
inputFile.lenght = 4256, len = 4256
”
这是解密的代码
byte[] salt = new byte[32];
FileStream fsCrypt = new FileStream(inputFile, FileMode.Open);
fsCrypt.Seek(fsCrypt.Length - 376, SeekOrigin.Begin);
fsCrypt.Read(salt, 0, salt.Length);
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
RijndaelManaged AES = new RijndaelManaged();
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new Rfc2898DeriveBytes(passwordBytes, salt, 50000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Padding = PaddingMode.PKCS7;
AES.Mode = CipherMode.CFB;
int read;
byte[] buffer = new byte[1048576];
List < byte > bytes = new List < byte > ();
fsCrypt.Seek(0, SeekOrigin.Begin);
read = 1;
var len = Convert.ToInt32(fsCrypt.Length);
MemoryStream mem = new MemoryStream();
fsCrypt.CopyTo(mem);
mem.Position = 0;
using(CryptoStream cryptoStream = new CryptoStream(mem, AES.CreateDecryptor(), CryptoStreamMode.Read)) // CryptoStream cryptoStream = new CryptoStream(fsCrypt, AES.CreateDecryptor(), CryptoStreamMode.Read
{
//var buffer2 = new byte[len];
while ((read = cs.Read(buffer, 0, buffer.Length)) > 0) {
foreach(var m in buffer)
bytes.Add(m);
}
}
你帮我吗?这段代码有什么问题?
我举了AES encryption on large files
的例子我如何加密:
byte[] salt = GenerateRandomSalt();
//convert password string to byte arrray
byte[] passwordBytes = System.Text.Encoding.UTF8.GetBytes(password);
//Set Rijndael symmetric encryption algorithm 71 246
RijndaelManaged AES = new RijndaelManaged();
AES.KeySize = 256;
AES.BlockSize = 128;
AES.Padding = PaddingMode.PKCS7;
var key = new Rfc2898DeriveBytes(passwordBytes, salt, 50000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CFB;
var kk = key.ToString();
FileStream fsIn = new FileStream(inputFile, FileMode.Open);
byte[] buffer = new byte[1048576];
int read = 0;
byte[] encrypted;
using(MemoryStream msEncrypt = new MemoryStream()) {
using(CryptoStream csEncrypt = new CryptoStream(msEncrypt, AES.CreateEncryptor(), CryptoStreamMode.Write)) {
fsIn.Seek(0, SeekOrigin.Begin);
while ((read = fsIn.Read(buffer, 0, buffer.Length)) > 0) {
csEncrypt.Write(buffer, 0, read);
}
encrypted = msEncrypt.ToArray();
}
}
fsIn.Seek(0, SeekOrigin.Begin);
fsIn.Write(encrypted, 0, encrypted.Length);
fsIn.Seek(fsIn.Length, SeekOrigin.Begin);
fsIn.Write(salt, 0, salt.Length);
答案 0 :(得分:1)
您在加密时过早地调用encrypted = msEncrypt.ToArray();
,它必须在csEncrypt
的using语句结束之后,因此所有数据都会被刷新到内存流中。
同样在您的解密中,您将开始在文件的早期
fsCrypt.Seek(fsCrypt.Length - 376, SeekOrigin.Begin);
如果您的fsCrypt.Seek(fsCrypt.Length - 32, SeekOrigin.Begin);
在写出时为salt.Length
,则应该mem
。
最后,在将盐传递给import UIKit
import AVFoundation
class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
@IBOutlet weak var messageLabel: UILabel!
static var isbn : String = ""
var captureSession:AVCaptureSession?
var videoPreviewLayer:AVCaptureVideoPreviewLayer?
var qrCodeFrameView:UIView?
let supportedCodeTypes = [AVMetadataObjectTypeEAN13Code]
override func viewDidLoad() {
super.viewDidLoad()
// Get an instance of the AVCaptureDevice class to initialize a device object and provide the video as the media type parameter.
let captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
do {
// Get an instance of the AVCaptureDeviceInput class using the previous device object.
let input = try AVCaptureDeviceInput(device: captureDevice)
// Initialize the captureSession object.
captureSession = AVCaptureSession()
// Set the input device on the capture session.
captureSession?.addInput(input)
// Initialize a AVCaptureMetadataOutput object and set it as the output device to the capture session.
let captureMetadataOutput = AVCaptureMetadataOutput()
captureSession?.addOutput(captureMetadataOutput)
// Set delegate and use the default dispatch queue to execute the call back
captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
captureMetadataOutput.metadataObjectTypes = supportedCodeTypes
// Initialize the video preview layer and add it as a sublayer to the viewPreview view's layer.
videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
videoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
videoPreviewLayer?.frame = view.layer.bounds
view.layer.addSublayer(videoPreviewLayer!)
// Start video capture.
captureSession?.startRunning()
// Move the message label and top bar to the front
view.bringSubview(toFront: messageLabel)
//view.bringSubview(toFront: topbar)
// Initialize QR Code Frame to highlight the QR code
qrCodeFrameView = UIView()
if let qrCodeFrameView = qrCodeFrameView {
qrCodeFrameView.layer.borderColor = UIColor.green.cgColor
qrCodeFrameView.layer.borderWidth = 2
view.addSubview(qrCodeFrameView)
view.bringSubview(toFront: qrCodeFrameView)
}
} catch {
// If any error occurs, simply print it out and don't continue any more.
print(error)
return
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - AVCaptureMetadataOutputObjectsDelegate Methods
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
// Check if the metadataObjects array is not nil and it contains at least one object.
if metadataObjects == nil || metadataObjects.count == 0 {
qrCodeFrameView?.frame = CGRect.zero
messageLabel.text = "No QR/barcode is detected"
return
}
// Get the metadata object.
let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
if supportedCodeTypes.contains(metadataObj.type) {
// If the found metadata is equal to the QR code metadata then update the status label's text and set the bounds
let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj)
qrCodeFrameView?.frame = barCodeObject!.bounds
if metadataObj.stringValue != nil {
messageLabel.text = metadataObj.stringValue
QRScannerController.isbn = metadataObj.stringValue
print(QRScannerController.isbn)
self.performSegue(withIdentifier: "showISBN", sender: self)
}
}
}
之前,您也不会将盐修剪掉,因此您将盐数据与密文一起传递到流中,这会使您的消息过长。