验证Android用户是否为人类(无验证码)

验证Android用户是否为人类(无验证码),android,captcha,bots,spam,google-cloud-messaging,Android,Captcha,Bots,Spam,Google Cloud Messaging,我有一个应用程序,用户可以添加评级,我不希望他们必须注册才能添加评级,但我也不希望机器人能够轻松地进行评级游戏 有没有一种方法可以合理地(不必是100%,但我不想使用反应式启发式方法)确保我的用户是人类?无需任何验证码/登录/其他操作。通常我会说这是不可能的,但由于我的应用程序运行在Android上,我认为我们可以做得更好 Gmail地址。 我的第一个想法是从AccountManager获取他们的gmail地址,但我找不到验证他们是否拥有该电子邮件地址的方法——也就是说,机器人可以向我的服务器发

我有一个应用程序,用户可以添加评级,我不希望他们必须注册才能添加评级,但我也不希望机器人能够轻松地进行评级游戏

有没有一种方法可以合理地(不必是100%,但我不想使用反应式启发式方法)确保我的用户是人类?无需任何验证码/登录/其他操作。通常我会说这是不可能的,但由于我的应用程序运行在Android上,我认为我们可以做得更好

Gmail地址。 我的第一个想法是从
AccountManager
获取他们的gmail地址,但我找不到验证他们是否拥有该电子邮件地址的方法——也就是说,机器人可以向我的服务器发送虚构的电子邮件,所以我认为这不可行(我不想让他们使用谷歌帐户验证我的应用程序;他们不太可能这样做)

GCM 我的下一个想法是使用谷歌的云消息服务。我可以从设备获取云消息ID,将其发送到我的服务器,从服务器将随机云消息发送回设备,然后将该消息发送回服务器。我认为这至少验证了他们确实有一个带有gmail帐户的Android设备,这已经足够好了

短讯服务 当然,我可以给他们发短信,但这要花钱,而且要做到无缝,就意味着我需要有权限阅读他们的短信,这是我真正想要避免的(特别是因为评级是一项可选功能)

安卓授权服务器 也许可以使用从谷歌获得用户从市场下载的签名保证,但由于我的应用程序的性质,我无法将其投放市场

设备ID、峨眉、电话号码等。 我当然不能用这些。机器人们可以编出来


因此,GCM看起来是最好(也是唯一)的选择。有人能想到其他什么吗?

随机显示一些弹出窗口,并将其关闭按钮放置在不同的位置,因此用户必须关闭它们

使用拖放API要求用户将按钮拖放到屏幕上的某个区域,然后提交评级。您可以随机放置按钮


您可以在多个位置拖动按钮,但可以指示用户将按钮放在正确的位置。

当您控制通信双方时,可以执行以下操作:

流动
  • 应用:从服务器请求一次性秘密令牌
  • 服务器:创建一次性秘密令牌和跟踪id并将两者发送到应用程序,同时使用跟踪id跟踪秘密令牌
  • 应用程序:使用一次性秘密令牌对投票进行加密(请参阅下面关于加密的内容)
  • 应用程序:向服务器发送加密邮件和跟踪id
  • 服务器:使用跟踪id查找秘密令牌,确保它尚未被使用,并使用秘密令牌解密投票
  • 加密 您可以使用任何对称加密技术。一个非常简单的例子是在应用程序端用秘密令牌对消息(即投票)进行异或。在服务器端,再次使用相同的秘密令牌执行XOR将再次发出普通消息


    只要攻击者不知道您的加密方法,此方法就是安全的。如果知道,他当然可以模拟应用程序所做的请求,但这对每种方法都适用,因此你可能应该使用比简单的异或更好的方法。

    在你的apk中放入私钥,从你的服务器下载一个随机文本,加密后发送回,你就会知道它来自你的apk。虽然你的GCM可能会工作,但是如果一个机器人可以从反编译的APK中获得私钥,那也是一样的。啊,我喜欢私钥的想法。显然,只要付出足够的努力,它是可以被破解的,但我可以让它变得困难。我想这可能就是答案!不过它刚刚发布:听起来像是传统验证码的蹩脚版本。我正试图避免用户输入。我不认为OP担心机器人会自动将他的Android应用程序发送虚假评论。我想他担心的是一个运行在PC上的机器人,HTTP向他的服务器发送评论,假装是从他的应用程序发送的。实际上它不需要人工,但它需要你的应用程序。正如所解释的,它不能被直接向服务器发送请求的Bot/脚本伪造。啊,与njzk2的建议相同。几乎只需“使用应用程序中包含的密钥对请求进行签名”。我不认为其他任何东西会增加任何安全性。它会增加安全性,因为应用程序中不包含密钥,所以反编译APK不会泄露它。通过使用一次性代币,你可以避免同一个人的多次投票——如果这是一个问题的话。不,本质上你的计划是“应用程序包含一个秘密”。您的秘密是算法,njzk2是密钥,但从安全角度看,这两者基本上没有区别。