【问题标题】:How to encrypt a ZipOutputStream in Google appengine?如何在 Google appengine 中加密 ZipOutputStream?
【发布时间】:2012-11-25 16:36:55
【问题描述】:

我正在使用 Java 在 GAE 中创建 zip 文件,并使用 ZipOutputStream 将它们上传到 Google Cloud Storage。

但是我需要加密文件但我不知道如何。

有人知道如何在 Google Appengine 中加密 ZipOutputStream 吗?

【问题讨论】:

标签: java google-app-engine google-cloud-storage zipoutputstream


【解决方案1】:

下面是一个示例 Java 应用程序,它演示了将文本块写入 zip 存档内的 DES 加密文件。应用程序的输出:

CloudStorageZipCrypto GET starting.
Creating file...
File created.
Writing to file: /gs/writable:<snipped>
Wrote to, closed, and finalized the file.
Reading file contents...
READ: The woods are lovely and deep.
READ: But I have promises too keep.

请注意,您也可以按相反的顺序执行此操作:将文件添加到 zip 并然后加密 zip 文件。它只需要切换密码和压缩流的顺序。这是源代码:

package com.jeffterrace.appenginetest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.channels.Channels;
import java.security.InvalidKeyException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.files.AppEngineFile;
import com.google.appengine.api.files.FileReadChannel;
import com.google.appengine.api.files.FileService;
import com.google.appengine.api.files.FileServiceFactory;
import com.google.appengine.api.files.FileWriteChannel;
import com.google.appengine.api.files.GSFileOptions.GSFileOptionsBuilder;

/**
 * Sample AppEngine Java class that reads and writes an encrypted, zipped file.
 */
public class CloudStorageZipCrypto extends HttpServlet {

  // Google Cloud Storage bucket name.
  private final String bucket = "jefftest1";
  // File name within the bucket.
  private final String filename = "test1.zip";
  // Text file within the zip file.
  private final String textFilename = "test1.txt.crypt";
  // The full Cloud Storage path for accessing the file from App Engine.
  private final String gsPath = "/gs/" + bucket + "/" + filename;

  // App Engine file service instance.
  private FileService fileService = FileServiceFactory.getFileService();

  // Secret key for DES encryption (only first 8 bytes are used).
  private final String secretKey = "thereisnospoon";

  @Override
  public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    resp.setContentType("text/plain");
    resp.getWriter().println("CloudStorageZipCrypto GET starting.");

    resp.getWriter().println("Creating file...");

    // Create the GCS file and open it for writing.
    GSFileOptionsBuilder optionsBuilder = new GSFileOptionsBuilder()
      .setBucket(this.bucket)
      .setKey(this.filename)
      .setAcl("public-read");
    AppEngineFile gcsFile = this.fileService.createNewGSFile(optionsBuilder.build());

    resp.getWriter().println("File created.");

    resp.getWriter().println("Writing to file: " + gcsFile.getFullPath());

    // Open a write channel to the GCS object.
    FileWriteChannel writeChannel = this.fileService.openWriteChannel(gcsFile, true);

    // Initialize what we need for encryption.
    DESKeySpec dks;
    SecretKeyFactory skf;
    SecretKey desKey;
    Cipher cipher;
    try {
      dks = new DESKeySpec(this.secretKey.getBytes());
      skf = SecretKeyFactory.getInstance("DES");
      desKey = skf.generateSecret(dks);
      cipher = Cipher.getInstance("DES");
      cipher.init(Cipher.ENCRYPT_MODE, desKey);
    } catch (Exception e) {
      resp.getWriter().println("Error initializing crypto: " + e);
      return;
    }

    // Create a zip file output stream and add a text file to it.
    ZipOutputStream zos = new ZipOutputStream(Channels.newOutputStream(writeChannel));
    zos.putNextEntry(new ZipEntry(textFilename));

    // Write some text to the file, through a cipher output stream so it gets encrypted.
    CipherOutputStream cos = new CipherOutputStream(zos, cipher);
    PrintWriter out = new PrintWriter(cos);
    out.println("The woods are lovely and deep.");
    out.println("But I have promises too keep.");

    // Close all the things
    out.close();
    cos.close();
    zos.close();
    writeChannel.closeFinally();

    resp.getWriter().println("Wrote to, closed, and finalized the file.");

    // Open the zip file back up from GCS
    gcsFile = new AppEngineFile(this.gsPath);
    FileReadChannel readChannel = fileService.openReadChannel(gcsFile, false);
    ZipInputStream zis = new ZipInputStream(Channels.newInputStream(readChannel));

    // Read in the first file as UTF-8.
    zis.getNextEntry();
    try {
      cipher.init(Cipher.DECRYPT_MODE, desKey);
    } catch (InvalidKeyException e) {
      resp.getWriter().println("Error initializing crypto: " + e);
      return;
    }
    CipherInputStream cis = new CipherInputStream(zis, cipher);
    BufferedReader reader = new BufferedReader(new InputStreamReader(cis, "UTF-8"));
    resp.getWriter().println("Reading file contents...");
    String line;
    while ((line = reader.readLine()) != null) {
      resp.getWriter().println("READ: " + line);
    }

    // Close all the things.
    reader.close();
    cis.close();
    zis.close();
    readChannel.close();
  }
}

【讨论】:

  • 你能说得更具体点吗?您到底在寻找什么?
  • 感谢您的回答,@jterrace。然而,这不是我要找的。我需要加密 zip 文件并允许用户使用密钥下载并使用解压缩软件(winzip、winrar ...)打开它。我认为您的代码加密了 zip 中的文件,而不是最终的 zip 文件。我可以?。抱歉之前的评论。
  • 我明白了,我认为您的意思是在 zip 文件中添加密码保护。
  • 我认为您的问题与this one重复
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-31
  • 2012-01-30
  • 2019-01-18
  • 1970-01-01
相关资源
最近更新 更多