电子版字体重整是不工作

问题描述:

我创建了使用雨燕2.电子版字体重整是不工作

我目前面临的问题是混淆字体/字体的mangling的iOS的EPUB 3阅读器。我已经阅读了一篇关于如何在Swift中实现这个功能的教程,并将其与我的项目进行了一些改编。

当我将一个模糊epub加载到我的应用程序中时,字体未正确加载并回退到其他系统字体。当我加载具有相同字体但未混淆的epub时,一切都很正常。很明显,这意味着我的混淆代码有问题,但是我不能在我的生活中发现错误。

这里是我的代码:

public struct Crypto { 

    public func obfuscateFontIDPF(data:NSData, key:String) -> NSData { 
    let source = data 
    var destination = [UInt8]() 
    let shaKey = key.sha1() 
    let keyData = shaKey.utf8Array 

    var arr = [UInt8](count: source.length, repeatedValue: 0) 
    source.getBytes(&arr, length:source.length) 

    var outer = 0 
    while outer < 52 && arr.isEmpty == false { 
     var inner = 0 
     while inner < 20 && arr.isEmpty == false { 
      let byte = arr.removeAtIndex(0)  //Assumes read advances file position 
      let sourceByte = byte 
      let keyByte = keyData[inner] 
      let obfuscatedByte = sourceByte^keyByte 
      destination.append(obfuscatedByte) 
      inner++ 
     } 
     outer++ 
    } 
    if arr.isEmpty == false { 
     while arr.isEmpty == false { 
      let byte = arr.removeAtIndex(0) 
      destination.append(byte) 
     } 
    } 

    let newData = NSData(bytes: &destination, length:  destination.count*sizeof(UInt8)) 
    return newData 
    } 
} 

extension String { 
    func sha1() -> String { 
    var selfAsSha1 = "" 

    if let data = self.dataUsingEncoding(NSUTF8StringEncoding) 
    { 
     var digest = [UInt8](count: Int(CC_SHA1_DIGEST_LENGTH), repeatedValue: 0) 
     CC_SHA1(data.bytes, CC_LONG(data.length), &digest) 

     for index in 0..<CC_SHA1_DIGEST_LENGTH 
     { 
      selfAsSha1 += String(format: "%02x", digest[Int(index)]) 
     } 
    } 

    return selfAsSha1 
    } 

    var utf8Array: [UInt8] { 
    return Array(utf8) 
    } 
} 

在这里,我所说的扰乱方法:

func parserDidEndDocument(parser: NSXMLParser) { 
     if encryptedFilePaths!.count != 0 { 
     for file in encryptedFilePaths! { 
      let epubMainDirectoryPath = NSString(string: epubBook!.epubMainFolderPath!).stringByDeletingLastPathComponent 
      let fullFilePath = epubMainDirectoryPath.stringByAppendingString("/" + file) 
      let url = NSURL(fileURLWithPath: fullFilePath) 
      if let source = NSData(contentsOfURL: url) { 
       let decryptedFont = Crypto().obfuscateFontIDPF(source, key: self.epubBook!.encryptionKey!) 
       do { 
        try decryptedFont.writeToFile(fullFilePath, options: .DataWritingAtomic) 
       } catch { 
        print(error) 
       } 
      } 
     } 
    } 
} 

如果你看到那里的错误可能,请让我知道。

+0

有趣的是,用真实的加密(AES)和公共的密码很可能是一对夫妇快几个数量级的。 – zaph

+0

@zaph是啊,不幸的是,我不是制作了Epub标准的。而且,这只是法律上的保护,将epub解压缩并提取字体非常简单。这只是为了合法保护发布商。 –

我想通了,这里是工作代码:

private func obfuscateData(data: NSData, key: String) -> NSData { 
    var destinationBytes = [UInt8]() 

    // Key needs to be SHA1 hash with length of exactly 20 chars 
    let hashedKeyBytes = generateHashedBytesFromString(key) 

    var sourceBytes = [UInt8](count: data.length, repeatedValue: 0) 
    data.getBytes(&sourceBytes, length: data.length) 

    var outerCount = 0 
    while outerCount < 52 && sourceBytes.isEmpty == false { 
     var innerCount = 0 
     while innerCount < 20 && sourceBytes.isEmpty == false { 
      let sourceByte = sourceBytes.removeAtIndex(0) 
      let keyByte = hashedKeyBytes[innerCount] 
      let obfuscatedByte = (sourceByte^keyByte) 
      destinationBytes.append(obfuscatedByte) 
      innerCount += 1 
     } 
     outerCount += 1 
    } 

    destinationBytes.appendContentsOf(sourceBytes) 
    let destinationData = NSData(bytes: &destinationBytes, length: destinationBytes.count*sizeof(UInt8)) 
    sourceBytes.removeAll(keepCapacity: false) 
    destinationBytes.removeAll(keepCapacity: false) 
    return destinationData 
} 

/// Convert the key string to a SHA1 hashed Byte Array 
private func generateHashedBytesFromString(string: String) -> [UInt8] { 
    var resultBytes = [UInt8]() 
    var hashedString = string.sha1() 

    for _ in 0.stride(to: hashedString.characters.count, by: 2) { 
     let character = "0x\(hashedString.returnTwoCharacters())" 
     resultBytes.append(UInt8(strtod(character, nil))) 
    } 
    return resultBytes 
} 


extension String { 
    func sha1() -> String { 
    var selfAsSha1 = "" 

    if let data = self.dataUsingEncoding(NSUTF8StringEncoding) { 
     var digest = [UInt8](count: Int(CC_SHA1_DIGEST_LENGTH), repeatedValue: 0) 
     CC_SHA1(data.bytes, CC_LONG(data.length), &digest) 

     for index in 0..<CC_SHA1_DIGEST_LENGTH { 
      selfAsSha1 += String(format: "%02x", digest[Int(index)]) 
     } 
    } 

    return selfAsSha1 
    } 

    mutating func returnTwoCharacters() -> String { 
     var characters: String = "" 
     characters.append(self.removeAtIndex(startIndex)) 
     characters.append(self.removeAtIndex(startIndex)) 
     return characters 
    } 
}