Encryption 如何以符合PCI的方式在iOS/Android上存储信用卡信息

Encryption 如何以符合PCI的方式在iOS/Android上存储信用卡信息,encryption,payment,pci-compliance,pci-dss,rncryptor,Encryption,Payment,Pci Compliance,Pci Dss,Rncryptor,我正在构建一个接受支付的移动应用程序。用户输入其CC详细信息,然后通过HTTPS将付款信息提交给零售商的POS系统。POS直接处理付款,需要实际的信用卡信息才能工作,因此我们不能使用Stripe之类的服务来存储卡,并返回令牌以处理付款 由于应用程序的性质,用户将定期付款,因此为了方便起见,我想存储他们的CC信息。但是,这不是重复计费,用户将随意启动交易。因此,我不需要将CC集中保存在服务器上,我正在考虑使用以下方法在每个用户的设备上存储单独的卡: 收集抄送号码和到期日期 使用AES256加密,

我正在构建一个接受支付的移动应用程序。用户输入其CC详细信息,然后通过HTTPS将付款信息提交给零售商的POS系统。POS直接处理付款,需要实际的信用卡信息才能工作,因此我们不能使用Stripe之类的服务来存储卡,并返回令牌以处理付款

由于应用程序的性质,用户将定期付款,因此为了方便起见,我想存储他们的CC信息。但是,这不是重复计费,用户将随意启动交易。因此,我不需要将CC集中保存在服务器上,我正在考虑使用以下方法在每个用户的设备上存储单独的卡:

  • 收集抄送号码和到期日期
  • 使用AES256加密,使用CVC作为密钥(CVC未存储)
  • 然后将加密数据存储在iOS密钥链(或Android的等效密钥链)中
  • 为了付款,(a)从钥匙链中取出数据,以及
  • (b) 用户必须输入CVC才能解密CC信息
这个想法是,如果用户知道CVC,他们无论如何都可能拥有该卡,因此他们不需要尝试破解该设备

对于加密,我正在考虑使用。其主要功能之一是将普通密码自动转换为两个256位密钥的加密“随机”字节序列,用于加密和身份验证。键拉伸通过10k轮PBKDF2实现。实施细节见链接,但简而言之:

  • AES-256加密
  • CBC模式
  • 使用PBKDF2扩展密码
  • 密码盐渍
  • 随机IV
  • 加密然后散列HMAC

问题:

我不太懂数学,无法判断RNCryptor的密钥拉伸实现是否只包含3个CVC数字,就能产生足够随机的密钥。我还没有找到任何关于RNCryptor保持安全所需的密码规范的文档。如果您对此有任何想法,我们将不胜感激。使用此库非常简单,如下所示:

//加密
NSData*数据=。。。
NSString*password=@“秘密密码”;
NSData*密文=[RNCryptor encryptData:数据密码:密码];
//解密
n错误*错误=nil;
NSData*明文=[RNCryptor decryptData:密文密码:密码错误:&错误];
如果(错误!=nil){
NSLog(@“错误:%@”,错误);
返回
}
// ...
当在iOS密钥链(或droid等效工具)上讲述AES256加密的抄送信息时,没有启用设备锁密码是否重要?我的想法是,信息已经加密了,它可以存储在设备上,而无需密钥链加密

在这种情况下,考虑到没有存储大量CC号码的中央服务器,PCI合规性的哪些部分与此相关?我试着阅读PCI规范,但这些文件是一个迷宫:(

  • 正如Ebbe指出的那样,仅使用CVC作为密钥,即使是从CVC派生的PBKDF2也是不安全的,只有1000个可能的密钥。密钥中必须包含其他内容

  • 由于日期的格式已知,且值有限,因此该日期起到了部分婴儿床的作用。此外,请注意不要包含任何其他婴儿床,如字段分隔符或字段指示器

  • 信用卡账号验证检查数字也是一个婴儿床

  • 为了确保钥匙链的安全,用户必须输入设备锁密码

  • 必须避免越狱和根设备,这很难确定

  • 只要只保存CC#和过期日期,而不保存任何track 2数据,并且按照PCI标准对其进行加密,您就可以了

  • 请参阅PCI,它在PCI站点上是免费的。请参阅表2,Application Developer

  • 最后找一位PCI审核员来审核您的方案,这只是“最佳信息”,提供的信息没有经过全面评估

  • 根据OP的评论进行更新:

    有1000个CVC需要尝试。RNCryptor每次CVC尝试大约需要200毫秒,这意味着所有1000个CVC都可以在大约4分钟内尝试。哎哟。RNCryptor具有身份验证功能,因此在尝试正确的CVC时可以立即知道。这一点都不安全,身份验证对您不利

    如果没有身份验证,则需要依赖crib。第一个crib是校验位,这将排除约900个CVC留下100个

    但更糟糕的是,这取决于加密的格式。使用不正确的密钥解密将返回基本上随机的字节。如果CC#和date是一个字符串,那么结果是数字字符串的几率实际上是压缩的,因此可以立即知道正确的解密。最好的办法是将CC#转换为一个大整数,然后将日期设置为数字日+年,并对其进行加密。但即使如此,仍有校验位和有效日期可用于验证解密。加密中不包含过期日期实际上更安全

    最后,使用CVC作为密钥将不安全,需要更长的密钥


    钥匙链不会保护其内容不受设备所有者的影响,实际上,设备所有者是谁拥有访问权,密码决定了访问权,从而决定了设备所有者。

    如果您不想自己实现所有内容,可以检查iOS和安卓的VGCollect SDK。SDK在PCI scop中收集所有数据e、 所有的加密工作人员都在他们这边完成,所以你只需要得到一个别名,你可以在发送付款请求时使用它。

    至少你需要验证iDevice是否启用了密码。Aes256需要一个256位的密钥,但cvc代码只包含10位的信息。如果使用cvc代码作为密钥,暴力不仅会破坏t