diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/AccessFilter.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/AccessFilter.java
index acadff3e509226bc502e116dafda51a902c89581..7302e6ff8658993f7af8ba9bee32318b49fad2ea 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/AccessFilter.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/AccessFilter.java
@@ -18,6 +18,7 @@ import net.i2p.util.SimpleTimer2;
 import net.i2p.util.Log;
 import net.i2p.util.SecureFileOutputStream;
 import net.i2p.data.Destination;
+import net.i2p.data.Hash;
 import net.i2p.i2ptunnel.I2PTunnelTask;
 import net.i2p.client.streaming.IncomingConnectionFilter;
 
@@ -33,11 +34,11 @@ class AccessFilter implements IncomingConnectionFilter {
     /**
      * Trackers for known destinations defined in access lists
      */
-    private final Map<String, DestTracker> knownDests = new HashMap<String, DestTracker>();
+    private final Map<Hash, DestTracker> knownDests = new HashMap<Hash, DestTracker>();
     /**
      * Trackers for unknown destinations not defined in access lists
      */
-    private final Map<String, DestTracker> unknownDests = new HashMap<String, DestTracker>();
+    private final Map<Hash, DestTracker> unknownDests = new HashMap<Hash, DestTracker>();
 
     AccessFilter(I2PAppContext context, FilterDefinition definition, I2PTunnelTask task) 
             throws IOException {
@@ -53,18 +54,18 @@ class AccessFilter implements IncomingConnectionFilter {
 
     @Override
     public boolean allowDestination(Destination d) {
-        String b32 = d.toBase32();
+        Hash hash = d.getHash();
         long now = context.clock().now();
         DestTracker tracker = null;
         synchronized(knownDests) {
-            tracker = knownDests.get(b32);
+            tracker = knownDests.get(hash);
         }
         if (tracker == null) {
             synchronized(unknownDests) {
-                tracker = unknownDests.get(b32);
+                tracker = unknownDests.get(hash);
                 if (tracker == null) {
-                    tracker = new DestTracker(b32, definition.getDefaultThreshold());
-                    unknownDests.put(b32, tracker);
+                    tracker = new DestTracker(hash, definition.getDefaultThreshold());
+                    unknownDests.put(hash, tracker);
                 }
             }
         }
@@ -89,7 +90,7 @@ class AccessFilter implements IncomingConnectionFilter {
                 for (DestTracker tracker : unknownDests.values()) {
                     if (!tracker.getCounter().isBreached(threshold))
                         continue;
-                    breached.add(tracker.getB32());
+                    breached.add(tracker.getHash().toBase32());
                 }
             }
             if (breached.isEmpty())
@@ -132,9 +133,9 @@ class AccessFilter implements IncomingConnectionFilter {
         }
 
         synchronized(unknownDests) {
-            for (Iterator<Map.Entry<String,DestTracker>> iter = unknownDests.entrySet().iterator();
+            for (Iterator<Map.Entry<Hash,DestTracker>> iter = unknownDests.entrySet().iterator();
                     iter.hasNext();) {
-                Map.Entry<String,DestTracker> entry = iter.next();
+                Map.Entry<Hash,DestTracker> entry = iter.next();
                 if (entry.getValue().purge(olderThan))
                     iter.remove();
             }
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/DestTracker.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/DestTracker.java
index 81d2b1f5b1fc811f05c8ac9d989f893074dcacff..4b034ca75b74d5e8c588eafb65409579a46e956a 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/DestTracker.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/DestTracker.java
@@ -1,20 +1,21 @@
 package net.i2p.i2ptunnel.access;
 
+import net.i2p.data.Hash;
 
 class DestTracker {
     
-    private final String b32;
+    private final Hash hash;
     private final Threshold threshold;
     private final AccessCounter counter;
 
-    DestTracker(String b32, Threshold threshold) {
-        this.b32 = b32;
+    DestTracker(Hash hash, Threshold threshold) {
+        this.hash = hash;
         this.threshold = threshold;
         this.counter = new AccessCounter();
     }
 
-    String getB32() {
-        return b32;
+    Hash getHash() {
+        return hash;
     }
 
     AccessCounter getCounter() {
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/ExplicitFilterDefinitionElement.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/ExplicitFilterDefinitionElement.java
index a318a16115e1c027d81707e68924009bbb85db04..1ce89c7462c63c534e8101812e97eb9eb8a33712 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/ExplicitFilterDefinitionElement.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/ExplicitFilterDefinitionElement.java
@@ -2,19 +2,21 @@ package net.i2p.i2ptunnel.access;
 
 import java.util.Map;
 
+import net.i2p.data.Hash;
+
 class ExplicitFilterDefinitionElement extends FilterDefinitionElement {
 
-    private final String b32;
+    private final Hash hash;
 
-    ExplicitFilterDefinitionElement(String b32, Threshold threshold) {
+    ExplicitFilterDefinitionElement(String b32, Threshold threshold) throws InvalidDefinitionException {
         super(threshold);
-        this.b32 = b32;
+        this.hash = fromBase32(b32);
     }
 
     @Override
-    public void update(Map<String, DestTracker> map) {
-        if (map.containsKey(b32))
+    public void update(Map<Hash, DestTracker> map) {
+        if (map.containsKey(hash))
             return;
-        map.put(b32, new DestTracker(b32, threshold));
+        map.put(hash, new DestTracker(hash, threshold));
     }
 }
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/FileFilterDefinitionElement.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/FileFilterDefinitionElement.java
index b515badc11fbc80873f80acff006b6890a015fb0..718bbf75ee76c8d4b7d47de413447985e38040a7 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/FileFilterDefinitionElement.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/FileFilterDefinitionElement.java
@@ -7,6 +7,8 @@ import java.io.BufferedReader;
 import java.io.FileReader;
 import java.io.IOException;
 
+import net.i2p.data.Hash;
+
 class FileFilterDefinitionElement extends FilterDefinitionElement {
 
     private final File file;
@@ -17,7 +19,7 @@ class FileFilterDefinitionElement extends FilterDefinitionElement {
     }
 
     @Override
-    public void update(Map<String, DestTracker> map) throws IOException {
+    public void update(Map<Hash, DestTracker> map) throws IOException {
         if (!(file.exists() && file.isFile()))
             return;
         BufferedReader reader = null; 
@@ -25,10 +27,13 @@ class FileFilterDefinitionElement extends FilterDefinitionElement {
             reader = new BufferedReader(new FileReader(file)); 
             String b32;
             while((b32 = reader.readLine()) != null) {
-                if (map.containsKey(b32))
+                Hash hash = fromBase32(b32);
+                if (map.containsKey(hash))
                     continue;
-                map.put(b32, new DestTracker(b32, threshold));
+                map.put(hash, new DestTracker(hash, threshold));
             }
+        } catch (InvalidDefinitionException bad32) {
+            throw new IOException("invalid access list entry", bad32);
         } finally {
             if (reader != null) {
                 try { reader.close(); } catch (IOException ignored) {}
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/FilterDefinitionElement.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/FilterDefinitionElement.java
index 821c3ff08e1b41949f52e1b9ad678aa01a65cf92..1160a79011d75a1112cb97f2e7f38475e7937898 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/FilterDefinitionElement.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/access/FilterDefinitionElement.java
@@ -3,6 +3,9 @@ package net.i2p.i2ptunnel.access;
 import java.util.Map;
 import java.io.IOException;
 
+import net.i2p.data.Hash;
+import net.i2p.data.Base32;
+
 abstract class FilterDefinitionElement {
 
     protected final Threshold threshold;
@@ -11,9 +14,16 @@ abstract class FilterDefinitionElement {
         this.threshold = threshold;
     }
 
-    abstract void update(Map<String, DestTracker> map) throws IOException;
+    abstract void update(Map<Hash, DestTracker> map) throws IOException;
 
     Threshold getThreshold() {
         return threshold;
     }
+
+    protected static Hash fromBase32(String b32) throws InvalidDefinitionException {
+        if (!b32.endsWith("b32.i2p"))
+            throw new InvalidDefinitionException("Invalid b32 " + b32);
+        b32 = b32.substring(0, b32.length() - 7);
+        return new Hash(Base32.decode(b32));
+    }
 }