菜鸟教程小白 发表于 2022-12-13 05:23:02

ios - 如何通过命令行在 Xcode 中登录 Apple ID?


                                            <p><p>我继承了一个 Xcode 设置,它构建了一个使用自动签名进行开发构建的 iOS 应用程序。我现在的任务是为这个项目构建一些 CI 设置,但<em>不改变实际的 Xcode 项目</em>。这意味着我暂时无法切换到手动签名。</p>

<p>由于项目在本地构建良好,我没想到这会成为一个大问题,但事实证明,自动签名(显然,事后看来)需要将您的 Xcode 登录到 Apple ID(Xcode => Preferences => Accounts) 应该用于自动创建证书。</p>

<p>有没有办法通过命令行将 Apple ID 添加到 Xcode?</​​p>

<hr/>

<p>这是我已经做过的:</p>

<p>我已经环顾四周,但无法通过 Google 找到任何明显的答案。 StackOverflow 上的所有问题和答案总是提到“只需快速打开 Xcode 并输入您的凭据”,遗憾的是这不适用于我们的 CI 设置。</p>

<p>我找到了 <a href="https://github.com/jenkinsci/xcode-plugin/blob/master/src/main/java/au/com/rayh/DeveloperProfileLoader.java" rel="noreferrer noopener nofollow">this Jenkins &#34;Xcode Plugin&#34;</a>这使您可以导入可以从 Xcode 导出的 <code>.developerprofile</code>。但是我的 Java 真的很生疏,我无法完全理解这是否“仅”导入配置文件和身份,或者帐户列表。 </p>

<p>我自己玩了一个 <code>.developerprofile</code>,它似乎在 <code>.zip</code> 文件中包含了帐户信息(以及所有证书等),因此您可以提取文件。这还包括 <code>accounts.keychain</code> 和 <code>accounts.plist</code>,但它们都用密码加密 - 我不知道如何使用它来获取真实数据在那里进一步调查。</p>

<p>如果您添加一个新的 Apple ID,我还试图找出 Xcode 最初保存信息的位置:它似乎将帐户名和密码以及一些 token 放入您的“登录”(<code>com.apple. gs.xcode.auth.com.apple.account.AppleIDAuthentication.token</code>)和“iCloud”钥匙串(keychain)(<code>Xcode-AlternateDSID</code> 和 <code>Xcode-Token</code>)。我也无法手动重新创建钥匙串(keychain)访问中的现有条目,因为“访问控制”->“此项目的访问组:”在手动创建应用程序密码时总是不同的。将项目复制到要导出的新钥匙串(keychain)中也不起作用,因为 <code>iCloud</code> 钥匙串(keychain)不允许我将内容复制到新钥匙串(keychain)(即使在 iCloud 中禁用钥匙串(keychain)同步后,所以钥匙串(keychain)被命名为“本地项目”)。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>首先,我不确定您尝试做的事情是否是一个好主意。 </p>

<p>请记住,如果您要将 Xcode 设置为<em>在每次构建时自动请求 iOS 开发人员证书</em>,并且该构建在不同的机器上执行(例如,托管 CI,例如 Travis 或 Azure Pipelines ),您的 iOS 开发者证书将被吊销并重新生成<em>每次</em>。</p>

<p>更好的选择(在我看来)是通过您的开发人员配置文件导出您的 iOS 开发证书和配置文件,并在您的构建环境中导入开发证书和配置文件。然后,如果需要,更新您的 Xcode 项目以使用您刚刚导入的证书和配置文件。</p>

<p>我认为 FaSTLane 已经可以做到几乎所有这些。如果你正在寻找灵感,Azure Pipelines 具有类似的功能。有一个任务<a href="https://github.com/microsoft/azure-pipelines-tasks/tree/master/Tasks/InstallAppleProvisioningProfileV1" rel="noreferrer noopener nofollow">installs a provisioning profile</a> , 其中一个 <a href="https://github.com/microsoft/azure-pipelines-tasks/tree/master/Tasks/InstallAppleCertificateV2" rel="noreferrer noopener nofollow">installs a certificate</a>和一个 <a href="https://github.com/microsoft/azure-pipelines-tasks/tree/master/Tasks/XcodeV5" rel="noreferrer noopener nofollow">builds an Xcode project and allows you to override the certificate and provisioning profiles used when signing your product</a> .</p>

<hr/>

<p>话虽如此,<code>accounts.plist</code> 和 <code>accounts.keychain</code> 可能包含您要查找的信息。这两个文件都使用 AES 加密。</p>

<p>用于加密文件的 key 是使用 PBKDF2(Password-Based Key Derivation Function 2)从密码导出的,使用这些参数:</p>

<ul>
<li>哈希函数:SHA256</li>
<li>密码:您的密码</li>
<li>Salt:密码的字节表示,使用 UTF8 编码</li>
<li>哈希迭代次数:33333</li>
<li> key 长度:10</li>
</ul>

<p>“魔数(Magic Number)”是 Apple 的 <code>SecKeyDeriveFromPassword</code> 函数使用的默认值,<a href="https://lapcatsoftware.com/articles/symmetric-encryption.html" rel="noreferrer noopener nofollow">as described here</a>和 <a href="https://opensource.apple.com/source/Security/Security-57337.60.2/OSX/libsecurity_keychain/lib/SecKey.cpp" rel="noreferrer noopener nofollow">implemented here</a> </p>

<p>获得加密 key 后,您可以解密文件。您需要一个初始化向量 (IV),这也是 Apple 使用的默认值 - 一个 16 字节的数组,完全由零组成。</p>

<p>在 C 语言中,您应该能够使用这样的代码来生成加密 key :</p>

<pre class="lang-c prettyprint-override"><code>CFStringRef password = CFSTR(&#34;verysecretstuff&#34;);
const char* saltBytes = CFStringGetCStringPtr(password, kCFStringEncodingUTF8);
CFDataRef salt = CFDataCreate(NULL, saltBytes, CFStringGetLength(password));

int keySizeInBits = kSecAES128;
CFNumberRef keySize = CFNumberCreate(NULL, kCFNumberIntType, &amp;keySizeInBits);

int rounds = 33333;
CFNumberRef numberOfRounds = CFNumberCreate(NULL, kCFNumberIntType, &amp;rounds);

CFMutableDictionaryRef parameters = CFDictionaryCreateMutable(NULL, 3, NULL, NULL);
CFDictionaryAddValue(parameters, kSecAttrKeyType, kSecAttrKeyTypeAES);
CFDictionaryAddValue(parameters, kSecAttrKeySizeInBits, keySize);
CFDictionaryAddValue(parameters, kSecAttrPRF, kSecAttrPRFHmacAlgSHA256);
CFDictionaryAddValue(parameters, kSecAttrRounds, numberOfRounds);
CFDictionaryAddValue(parameters, kSecAttrSalt, salt);

CFErrorRef error = NULL;
SecKeyRef key = SecKeyDeriveFromPassword(password, parameters, &amp;error);
</code></pre>

<p>要解密数据,请使用:</p>

<pre class="lang-c prettyprint-override"><code>const UInt *bytes = NULL; // Encrypted data
CFDataRef data = CFDataCreate(NULL, bytes, length);

CFErrorRef error = NULL;
SecTransformRef transform = SecDecryptTransformCreate(key, &amp;error);
if ( transform == NULL )
{
    CFShow(error);
    CFRelease(error);
}

SecTransformSetAttribute(transform, kSecEncryptionMode, kSecModeCBCKey, &amp;error);
SecTransformSetAttribute(transform, kSecPaddingKey, kSecPaddingPKCS7Key, &amp;error);
SecTransformSetAttribute(transform, kSecTransformInputAttributeName, data, &amp;error);
CFDataRef result = SecTransformExecute(transform, &amp;error);

CFShow(result);

CFRelease(result);
CFRelease(data);
CFRelease(transform);
</code></pre>

<p>希望对你有帮助!</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 如何通过命令行在 Xcode 中登录 Apple ID?,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/54787309/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/54787309/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 如何通过命令行在 Xcode 中登录 Apple ID?