diff --git a/apps/i2psnark/java/src/org/klomp/snark/MetaInfo.java b/apps/i2psnark/java/src/org/klomp/snark/MetaInfo.java
index 28677addaf2d361a291eee0590ef0187558feb39..648a055243f25dd3668421154382c7b362bbb78f 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/MetaInfo.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/MetaInfo.java
@@ -61,6 +61,7 @@ public class MetaInfo
   private final int piece_length;
   private final byte[] piece_hashes;
   private final long length;
+  private final boolean privateTorrent;
   private Map<String, BEValue> infoMap;
 
   /**
@@ -71,7 +72,7 @@ public class MetaInfo
    *  @param lengths null for single-file torrent
    */
   MetaInfo(String announce, String name, String name_utf8, List<List<String>> files, List<Long> lengths,
-           int piece_length, byte[] piece_hashes, long length)
+           int piece_length, byte[] piece_hashes, long length, boolean privateTorrent)
   {
     this.announce = announce;
     this.name = name;
@@ -82,6 +83,7 @@ public class MetaInfo
     this.piece_length = piece_length;
     this.piece_hashes = piece_hashes;
     this.length = length;
+    this.privateTorrent = privateTorrent;
 
     // TODO if we add a parameter for other keys
     //if (other != null) {
@@ -160,6 +162,10 @@ public class MetaInfo
     else
         name_utf8 = null;
 
+    // BEP 27
+    val = info.get("private");
+    privateTorrent = val != null && val.getString().equals("1");
+
     val = info.get("piece length");
     if (val == null)
         throw new InvalidBEncodingException("Missing piece length number");
@@ -318,6 +324,14 @@ public class MetaInfo
     return name;
   }
 
+  /**
+   * Is it a private torrent?
+   * @since 0.9
+   */
+  public boolean isPrivate() {
+    return privateTorrent;
+  }
+
   /**
    * Returns a list of lists of file name hierarchies or null if it is
    * a single name. It has the same size as the list returned by
@@ -439,7 +453,7 @@ public class MetaInfo
   {
     return new MetaInfo(announce, name, name_utf8, files,
                         lengths, piece_length,
-                        piece_hashes, length);
+                        piece_hashes, length, privateTorrent);
   }
 
   /**
@@ -475,6 +489,10 @@ public class MetaInfo
     info.put("name", name);
     if (name_utf8 != null)
         info.put("name.utf-8", name_utf8);
+    // BEP 27
+    if (privateTorrent)
+        info.put("private", "1");
+
     info.put("piece length", Integer.valueOf(piece_length));
     info.put("pieces", piece_hashes);
     if (files == null)
diff --git a/apps/i2psnark/java/src/org/klomp/snark/Storage.java b/apps/i2psnark/java/src/org/klomp/snark/Storage.java
index ffd6f25090a1d68193202a4063b702dc18f9c66d..51c1ff46188beacb1943efa0db93424c0b07debc 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/Storage.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/Storage.java
@@ -101,7 +101,8 @@ public class Storage
    * @param announce may be null
    * @param listener may be null
    */
-  public Storage(I2PSnarkUtil util, File baseFile, String announce, StorageListener listener)
+  public Storage(I2PSnarkUtil util, File baseFile, String announce,
+                 boolean privateTorrent, StorageListener listener)
     throws IOException
   {
     _util = util;
@@ -157,7 +158,7 @@ public class Storage
 
     byte[] piece_hashes = fast_digestCreate();
     metainfo = new MetaInfo(announce, baseFile.getName(), null, files,
-                            lengthsList, piece_size, piece_hashes, total);
+                            lengthsList, piece_size, piece_hashes, total, privateTorrent);
 
   }
 
diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
index 4898ddaf4a73c2fac527cc3ccc08de8f3401aef6..dda9be36f67b846c0336f66c8e2a408416124f5c 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
@@ -668,7 +668,7 @@ public class I2PSnarkServlet extends Default {
                     try {
                         // This may take a long time to check the storage, but since it already exists,
                         // it shouldn't be THAT bad, so keep it in this thread.
-                        Storage s = new Storage(_manager.util(), baseFile, announceURL, null);
+                        Storage s = new Storage(_manager.util(), baseFile, announceURL, req.getParameter("private") != null, null);
                         s.close(); // close the files... maybe need a way to pass this Storage to addTorrent rather than starting over
                         MetaInfo info = s.getMetaInfo();
                         File torrentFile = new File(_manager.getDataDir(), s.getBaseName() + ".torrent");