【问题标题】:How to modify source code of app after Building? xCode-Sparkle构建后如何修改应用程序的源代码? xCode-Sparkle
【发布时间】:2016-10-04 21:48:59
【问题描述】:

我正在做一个需要使用两个变量的 Mac 代理,每次用户下载代理时都需要设置这两个变量,我的第一次尝试是修改 Info.plist 文件并为 Sparkle 进行签名,但在那之后我意识到,每次我修改那个文件并进行签名时,这个签名都会与已经下载的代理不同,并且可能会导致 Sparkle 出现问题:

  1. 出于安全考虑考虑由于 Sparkle 正在将可执行代码下载到您用户的系统中,因此您必须非常注意安全性。 让 Sparkle 知道下载的更新没有损坏并且来了 来自您(而不是恶意攻击者),我们建议:列出项目

    • 使用与应用中包含的公共 DSA 密钥匹配的 DSA 签名对已发布的更新存档进行代码签名。

https://sparkle-project.org/documentation/

关于如何实现这一点的任何建议?

这是我用来修改和签名的脚本:

import plistlib, sys, tempfile, subprocess, os, datetime


# Read the plist file generated by xCode, and write the OrganizationID and OrganizationToken.
plist_file = plistlib.Plist.fromFile("Agent.app/Contents/Info.plist") 
plist_file['OrganizationID'] = sys.argv[1]
plist_file['OrganizationToken'] = sys.argv[2]


plistlib.writePlist(plist_file, "Agent.app/Contents/Info.plist")

VERSION = plist_file['CFBundleVersion']
DOWNLOAD_BASE_URL="https://url/core/mac/agent"
RELEASENOTES_URL= DOWNLOAD_BASE_URL + "/release-notes.html#version-$VERSION"
ARCHIVE_FILENAME="Agent %s.zip" % str(VERSION)
DOWNLOAD_URL="%s/$%s" % (DOWNLOAD_BASE_URL, ARCHIVE_FILENAME)
KEYCHAIN_PRIVKEY_NAME="sparkle_private_key/dsa_priv.pem"
os.environ['openssl']= "/usr/bin/openssl"
SIGNATURE= '$openssl dgst -sha1 -binary < "%s" | $openssl dgst -dss1 -sign "%s" | $openssl enc -base64' %  (ARCHIVE_FILENAME, KEYCHAIN_PRIVKEY_NAME)
signature = subprocess.check_output(SIGNATURE, shell=True).strip()
SIZE = 'stat -f %%z "%s"' % ARCHIVE_FILENAME
size = subprocess.check_output(SIZE, shell=True).strip()
PUBDATE = 'LC_TIME=en_US date +"%a, %d %b %G %T %z"'
pubdate = subprocess.check_output(PUBDATE, shell=True).strip()


xml = '''<rss xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
<channel>
<title>Update</title>
<link>
http://sparkle-project.org/files/sparkletestcast.xml
</link>
<description>Most recent changes with links to updates.</description>
<language>en</language>
<item>
<title>Version %s</title>
<sparkle:releaseNotesLink>
%s
</sparkle:releaseNotesLink>
<pubDate>%s</pubDate>
<enclosure
url="%s"
sparkle:version="%s"
type="application/octet-stream"
length="%s"
sparkle:dsaSignature="%s"
/>
</item>
</channel>
</rss>''' % (VERSION, RELEASENOTES_URL, pubdate, DOWNLOAD_URL, VERSION,  size, signature)

【问题讨论】:

    标签: xcode macos info.plist sparkle


    【解决方案1】:

    如果您的意思是每个下载的用户都应该获得一个唯一的捆绑包(其 Info.plist 已被修改的捆绑包)来下载,即您打算为每次下载再次计算一个新的 DSA 签名(这就是您的问题的方式理解),您打算做的不是对 HTTP 缓存非常友好(您的服务器或您的服务器和最终用户的机器之间的任何东西都将能够缓存正在下载的应用程序存档)。除非下载的包很小,否则我不鼓励这样做。事实上,由于如今Developer ID signing 是在大多数 Mac 上轻松成功部署您的软件所必需的(Sierra 使未签名的应用程序部署更加困难),您不仅需要重新创建 Sparkle 的 DSA 签名(这实际上是可选的,见下文),但在 Info.plist 内容更改后使用codesign 自行重新签署应用程序包内容,这意味着为您的代理下载提供服务的服务器需要运行 macOS 并包含开发人员工具。

    顺便说一句,DSA 签名验证由 Sparkle is optional 完成,并且仅在应用未签名开发者 ID(或者应用广播通过 HTTP – which is otherwise also vulnerable to exploits 提供)时完成。

    如果不知道您打算保留什么样的每用户状态,我会提出某种方案,您的应用会回调您的服务以获取变量值(例如传入一些输入主机身份,例如 MAC addressserial number 的一些加盐哈希,或者甚至只是每个用户创建的一些随机值,如果用户篡改它并不重要,则存储在用户默认值中),你也可以这样做 runtime signature validations when the app is running以确保最终用户不会篡改应用程序。

    我希望这会有所帮助!我不确定我是否完全正确地提出了您的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-04
      • 2010-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多