首页 文章

如何在构建后修改应用程序的源代码? Xcode中,旌宇

提问于
浏览
4

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

考虑安全问题由于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)

1 回答

  • 1

    如果您的意思是每个用户下载应该获得一个唯一的捆绑包(Info.plist已被修改的捆绑包)下载,即您打算为每次下载再次计算新的DSA签名('s how your question can be understood), what you intend to do isn'非常HTTP缓存友好(您的服务器和最终用户的机器之间没有任何东西都可以缓存正在下载的应用程序存档 . 除非下载的软件包很小,否则我不鼓励这样做 . 事实上,这几天实际上需要Developer ID signing才能获得你的服务器软件在大多数Mac上毫不费力地成功部署(Sierra使得未签名的应用程序部署更加困难),您不仅需要重新创建Sparkle的DSA签名(实际上是可选的,请参阅下文),而是使用 codesign 重新签署应用程序包内容本身在Info.plist内容发生更改后,意味着为您的代理下载服务的服务器需要运行macOS并包含开发人员工具 .

    顺便说一句,由Sparkle is optional完成的DSA签名验证仅在应用程序未签署开发者ID时(或者如果通过HTTP提供appcast,则完成) - which is otherwise also vulnerable to exploits .

    如果不了解您打算保留的每个用户状态的更多信息,我会提出某种方案,您的应用程序会回调您的服务以获取变量值(例如传入输入一些主机标识,例如作为MAC addressserial number的一些盐渍哈希,或者甚至只是每个用户创建的一些随机值,如果用户篡改它存储在用户默认值中并不重要),你也会做runtime signature validations when the app is running以确保最终用户不被篡改与应用程序 .

    我希望这有帮助!我不确定我的问题根据它的实际情况而完全正确 .

相关问题