从pubnub收到消息时,没有关于发件人的信息。如何知道来自visitorA或visitorB的消息?网上有一些例子,发件人用信息发送了他的名字,但是如何知道他不是在欺骗别人的身份呢?
这是一个聊天界面的示例:
<html>
<body>
<form id="message_form">
<input id="message_input" type="text"/>
</form>
<div id="chat"></div>
<script src="http://cdn.pubnub.com/pubnub-3.7.1.min.js"></script>
<script>
var pubnub = PUBNUB.init({
publish_key: 'demo',
subscribe_key: 'demo'
});
pubnub.subscribe({
channel: 'chat',
message: function(message){
var div = document.createElement("div");
div.textContent = message;
var chat = document.getElementById("chat");
chat.appendChild(div);
}
});
var form = document.getElementById("message_form");
form.onsubmit = function(e) {
var input = document.getElementById("message_input");
pubnub.publish({
channel: 'chat',
message: input.value
});
input.value = '';
e.preventDefault();
};
</script>
</body>
</html>
答案 0 :(得分:5)
您可以通过创建唯一ID 以及附加到聊天会话的消息有效内容的名称来识别发件人。这类似于IRC策略,但更简单一些。
var user_id = PUBNUB.uuid();
var user_name = name.value;
var user_message = input.vaule;
这是一个完整的示例,其中包含UserName输入的HTML元素。另请注意,我添加了safe_text()
方法来防止XSS攻击。
<form id="message_form">
Name: <input id="name_input" value="John" type="text"/><br>
Message: <input id="message_input" value="Hi" type="text"/><br>
<input type="submit" value="send">
</form>
<div id="chat"></div>
<script src="http://cdn.pubnub.com/pubnub-dev.js"></script>
<script>
var userid = PUBNUB.uuid();
var pubnub = PUBNUB({
publish_key : 'demo',
subscribe_key : 'demo',
uuid : userid
});
function safe_text(text) {
return (''+text).replace( /[<>]/g, '' );
}
pubnub.subscribe({
channel: 'chat',
message: function(message){
var div = document.createElement("div");
div.textContent =
safe_text(message.name) + ": " +
safe_text(message.text);
var chat = document.getElementById("chat");
chat.appendChild(div);
}
});
var form = document.getElementById("message_form");
form.onsubmit = function(e) {
var input = document.getElementById("message_input");
var name = document.getElementById("name_input");
pubnub.publish({
channel: 'chat',
message: { name : name.value, text : input.value, userid :userid }
});
input.value = '';
e.preventDefault();
};
</script>
虽然此演示为您提供了一个快速简便的入门应用,但您需要添加更多enhanced chat security and chat authentication systems。
有关构建聊天应用程序的其他资源,请查看Build Real-time Chat Apps in 10 Lines of Code指南以及Building A Basic Chat Application。
您需要添加Security ACL Access Control Layer。使用PubNub Access Manager(PAM),您可以通过授予用户访问权限的权限来控制谁有权访问。
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Grant Chat Access to Secured Conversations
// All server-side data is stored according to defined security policies.
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
var pubnub = PUBNUB({
publish_key: "PUBLISH_KEY",
subscribe_key: "SUBSCRIBE_KEY",
secret_key: "SECRET_KEY"
})
pubnub.grant({
channel : "CHANNEL",
callback : receiver,
error : receiver,
ttl : 60, // Minutes
read : true,
write : true,
auth_key : "AUTH_KEY"
});
建议在可信系统(例如您自己的数据中心服务器)上运行此级别的ACL代码。
PubNub客户端库提供内置的高级加密标准(AES)256位加密。要使用消息加密,只需在初始化时使用cipher_key。
使用TLS和ssl
标志启用传输层加密。
然后像往常一样发布/订阅。
var pubnub = PUBNUB({
subscribe_key: 'sub-c-f762fb78-...',
publish_key: 'pub-c-156a6d5f-...',
ssl: true,
cipher_key: 'my_cipherkey'
});
将用户的信息附加到每条消息是有效的,并在您的应用程序中提供非常强大的灵活性。但是,恶意用户可能会试图欺骗用户的身份,并因此冒充其他用户。在示例应用中,我们已经证明,通过在"message_form"
字段中更改您的姓名,很容易冒充任何人。这与您在电子邮件和SMTP中遇到的情况相同,其中可以进行任意电子邮件标头模拟,除非您提供验证发件人身份的方法。有一个解决方案!
数字签名是指纹,其中包含消息有效负载的关键组件的嵌入式安全加密散列,可选地包括salt(有时是时间戳),然后使用非对称密钥进行签名/加密,该密钥用于验证发送方的身份。此过程用于阻止欺骗者和模仿。
首先假设只有聊天用户被授予了访问权限,他们可以使用PubNub Access Manager实施中提供的grant
和revoke
技术发布和订阅聊天频道。
这里面临的挑战是,在群聊室中,您的聊天用户已被授予auth_tokens
,但他们仍然可以冒充该频道上的其他聊天用户。
这里的目标是在客户收到消息时验证两件事。
使用非对称加密技术,您可以为用户提供一层验证和安全性。通过创建数字签名来创建消息。有效的数字签名使收件人有理由相信该邮件是由已知发件人创建的,发件人不能拒绝发送邮件(身份验证和不可否认),并且邮件在传输过程中未被更改(完整性)。数字签名通常用于金融交易和面向消息的通信,如电子邮件和聊天,在其他情况下,检测伪造或篡改非常重要。
您将首先发布每个聊天用户&#39;一组密钥,服务器生成,在用户登录后通过您的服务器使用公钥(非对称)算法(如ECC / RSA)。我建议使用ECC,因为密钥大小比RSA小得多,具有可比较的加密强度。聊天室中的每个聊天用户都会收到其他聊天用户的通知。公钥通过安全的只读侧通道。您的用户只能从由您的服务器的可信和安全环境控制的公共READ-ONLY通道接收公钥。您的服务器将能够将每个用户的公钥写入此READ-ONLY通道。您的用户将从此频道中阅读。
在加入聊天室之前,您的用户可以通过PubNub历史记录呼叫接收彼此的公钥。他们还应该开放订阅同一频道,以获取加入聊天室的新聊天用户的公钥。
用户&#39;除经过验证的所有者外,私钥不得向任何人公开。这可以通过电子邮件/密码登录完成,您可以在登录后立即将私钥发送给经过验证的用户。
{ userId: 123456,
profilePic: "http://www.chats.com/user1234.jpg",
message: "Hello World",
signature: "tnnArxj06cWHq44gCs1OSKk/jLY" }
您将通过连接以下基本字符串 (userId+profilePic+message)
来创建签名。接下来,您需要使用SHA1(signature_base_string)
或SHA256(signature_base_string)
计算邮件摘要。现在,您可以使用此加密生成的哈希与用户签名&#39;私钥使用ECC / RSA非对称算法。
现在将此数字签名附加到聊天消息,如上面的示例所示,并连接到聊天室消息验证的最后阶段。
订阅聊天室频道时,您将收到附带数字签名的用户发送的聊天消息。您将使用此签名来验证聊天消息的真实性。如果邮件是尝试欺骗,您将完全放弃该邮件。
// Digitally Signed Chat Message
{ userId: 123456,
profilePic: "http://www.chats.com/user1234.jpg",
message: "Hello World",
signature: "tnnArxj06cWHq44gCs1OSKk/jLY" }
要验证签名,您将通过连接以下基本字符串 (userId+profilePic+message)
来创建签名。接下来,您需要使用SHA1(signature_base_string)
或SHA256(signature_base_string)
计算邮件摘要。现在使用聊天用户&#39;您已经拥有userid 123456的公钥,您可以验证/解密数字签名,以获取您刚刚生成的原始邮件摘要,该摘要也是由发件人创建的。
比较当前消息摘要和原始消息摘要。如果它们相同,则邮件是可信的,并且您已通过数字签名使用邮件验证成功验证了发件人的邮件。如果摘要不匹配,则表示虚假消息,您可以忽略模仿者。
您需要通过只读PKI 安全传输公钥的方法。 PubNub为您提供了一种为聊天用户公开安全只读PKI 列表的方法。需要注意的是,PKI需要非对称密钥算法,如ECC或RSA。我们还使用这些加密算法来创建数字签名而不是加密数据。这意味着我们将能够通过使用公钥成功解密签名并验证盐渍签名字符串匹配来识别和验证发件人。
请务必注意,您只应打印从公钥可信来源检索的用户名,而不是邮件内容。消息内容仅用于签名和验证身份。如果更改了身份,则必须使用PubNub的广播机制和存储和回放进行安全授权,通过PKI进行中继。
访问令牌,身份名称/照片和非对称密钥只能从服务器上的可信执行环境生成,并通过PubNub的授权只读PKI数据通道进行中继。
答案 1 :(得分:1)
在最新的PubNub SDKs(v4)中,发布者UUID现已包含在订阅响应中。
{
actualChannel: null,
channel: "my_channel_1",
message: "Hello World!",
publisher: "pn-58e1a647-3e8a-4c7f-bfa4-e007ea4b2073",
subscribedChannel: "my_channel_1",
subscription: null,
timetoken: "14966804541029440"
}