我会尽量简短,但我会分享整个画面。
问题陈述
我正在使用来自tippecanoe的矢量图块从我的数据mapbox
中创建。问题是,在 Web 客户端上,当我看到并下载并通过此(mapbox-vector-tile-cs)库运行它时,我能够成功地从图块中获取数据。这意味着任何有一些基本谷歌搜索的人也可以从矢量图块中窃取我的数据。.pbtiles
geojson
inspect element
.pbf
我能够实现的目标
为了避免安全问题,我的时间表很短,我想出了一个快速而肮脏的方法。tippecanoe
创建sqlite db后.mbtiles
,我运行一个 java 实用程序来加密blob
使用AES 256
加密中的数据,并以两种不同的方式将其存储在两个不同的 sqlite db 中:
以字节形式存储到不同的
.mbtiles
sqlite 数据库中(存储为 Blob)。随着z, x, y
和metadata
将加密数据编码为
base64
,然后将 base64 编码的加密切片数据存储到字符串数据类型列中。随着z, x, y
和metadata
。并将密钥(base64 编码)和初始化向量(base64 编码)存储到一个文件中。
API 端(问题 1)
现在,当我.pbf
从 API 获得未加密的数据时,会设置一个类型的标头,gzip
并application/x-protobuf
设置有助于将未加密的blob
数据转换为 aprotobuf
并返回一个.pbf
下载的文件。
现在,当我尝试从 API 中获取与未加密时具有相同标头的加密数据时,下载.pbf
失败说Failed - Network error
. 我意识到这是由于标头application/x-protobuf
试图将文件打包到一段.pbf
时间内造成的,blob 的内容可能与预期不匹配,因此结果不匹配。
我删除了标题application/x-protobuf
,因为我现在不能gzip
,所以我也删除了标题gzip
。现在数据显示在 chrome 浏览器上而不是被下载,我认为现在它只是一个随机响应。
问题是,我怎样才能让它发送一个.pbf
包含加密数据的文件,并且这个((mapbox-vector-tile-cs))库可以解析数据?我知道在传递它之前需要先解密数据,因为parsing
假设它已被解密并且我有存储blob
到.mbtiles
.
这个带有 UWP 项目的库(问题 2)
所以现在如上所述(因为我没有标题部分的解决方案)我删除了标题并让 API 返回一个直接响应。
我现在面临的问题是,当我将解密的(我检查解密成功并且解密的数据与存储在其中的内容完全匹配Blob
)Blob 数据传递给
var layerInfos = VectorTileParser.Parse(stream);
代码行返回我一个IEnumerable<Tile>
that isnot null
但里面有0 layers
。而实际的瓷砖包含5 layers
在其中。
我的问题是,我如何让这个((mapbox-vector-tile-cs))库返回图层。
在我发送之前从服务器获取图块并解密的代码parsing
如下:
//this code downloads the tile, layerInfos is returned as an empty collection
private async Task<bool> ProcessTile(TileData t, int xOffset, int yOffset)
{
var stream = await GetTileFromWeb(EncryptedTileURL,true);
if (stream == null)
return false;
var layerInfos = VectorTileParser.Parse(stream);
if (layerInfos.Count == 0)
return false;
return true;
}
使用以下GetTileFromWeb()
方法从服务器获取图块:
private async Task<Stream> GetTileFromWeb(Uri uri, bool GetEnc = false)
{
var handler = new HttpClientHandler();
if (!GetEnc)
handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
var gzipWebClient = new HttpClient(handler);
var bytes = gzipWebClient.GetByteArrayAsync(uri).Result;
if (GetEnc)
{
var decBytes = await DecryptData(bytes);
return decBytes;
}
var stream = new MemoryStream(bytes);
return stream;
}
PS:抱歉这么长的问题,我不习惯如此详尽的细节,但似乎我需要分享更多,因为加密是我的长处,而地图数据矢量瓦片不是。