Создание аппаратного идентификатора компьютера - PullRequest
5 голосов
/ 26 мая 2011

У меня был вопрос относительно генерации определенного идентификатора компьютера для целей лицензирования.Предпочтительно этот идентификатор должен быть аппаратным и, следовательно, не должен изменяться, если пользователь переформатирует, например.Кроме того, пользователю не должно быть легко (или предпочтительно даже невозможно) изменить информацию, из которой генерируется идентификатор.В настоящее время я объединяю только два компонента: стандарт CPUID и флаги функций, а также геометрию и общий размер первого физического диска в машине.Хотя это кажется хорошим для большинства обычных ПК, многие нетбуки, например, сделаны с одинаковым оборудованием, и в этом случае вы получите один и тот же идентификатор для многих машин.Кто-нибудь из вас может предложить какой-то другой аппаратный компонент, который я мог бы использовать?

У меня есть два требования:

  1. Он не должен использовать WMI.

  2. Он должен работать в большом количестве ситуаций (в том числе для пользователей без или с несколькими привилегиями).Я думал об использовании серийного номера физического диска, но это, кажется, трудно восстановить, если пользователь не находится в режиме администратора.

Я работаю в C ++ на Windows.

Заранее благодарен за любые предложения.

С уважением,

Филип Беннфол

Ответы [ 6 ]

4 голосов
/ 26 мая 2011

Вы можете использовать первый MAC-адрес, который назначается производителем оборудования и никогда не изменится.

Примерно так:

/** 

  return string containing first MAC address on computer

 requires adding Iphlpapi.lib to project

*/
string GetMac()
{
    char data[4096];
    ZeroMemory( data, 4096 );
     unsigned long  len = 4000;
    PIP_ADAPTER_INFO pinfo = ( PIP_ADAPTER_INFO ) data;
    char sbuf[20];
    string sret;

    DWORD ret = GetAdaptersInfo( pinfo, &len );
    if( ret != ERROR_SUCCESS )
        return string("**ERROR**");

    for(int k = 0; k < 5; k++ ) {
        sprintf(sbuf,"%02X-",pinfo->Address[k]);
        sret += sbuf;
    }
    sprintf(sbuf,"%02X",pinfo->Address[5]);
    sret += sbuf;

    return( sret );
}

ИМХО, этого достаточно для лицензирования программного обеспечения на сумму до тысячи долларов, где все, что необходимо, - это предотвратить случайное использование вашего программного обеспечения соседями. Мотивированный пират может обойти это, но пираты с достаточными знаниями и мотивацией не достаточно часты, чтобы вам стоило потратить больше усилий, пытаясь победить их, и, что еще более важно, вы не хотите причинять неудобства своим честным клиентам.

Если ваше программное обеспечение настолько ценно, что мотивированные пираты представляют собой реальную угрозу, тогда стоимость и неудобство аппаратного ключа становятся оправданными.

Я также не верю в нагромождение дополнительных аппаратных сигнатур, идентификаторов дисков, конфигураций материнских плат и так далее. Повышение безопасности минимально, и вероятность того, что что-то может пойти не так, значительно возрастает, так что вы в конечном итоге будете тратить часы на поддержку клиентов с необычными настройками и разозлите неизвестные номера, которые просто разочаровываются в вас.

Реализация простой системы с MAC-адресом, которая, кажется, всегда работает. Примите, что случайный пират может получить свои удары от нарушения вашей лицензии. Сконцентрируйте свои усилия на улучшении своего программного обеспечения, чтобы вы получили больше честных клиентов.

Система может иметь более одной сетевой карты (например, ethernet и беспроводная сеть), и пользователь может изменить порядок представления (зачем ему это делать?). Чтобы справиться с этим, лицензия должна соответствовать сетевой карте, присутствующей в любом месте системы, требуя код примерно такой:

/**

  The MAC addresses of ethernet network cards present on computer

  @param[out] vMAC vector of strings containing MAC addresses in XX-XX-XX-XX-XX-XX format

  returns empty vector on error

  See discussion of this 
  /5437934/sozdanie-apparatnogo-identifikatora-kompytera

*/

void cLicenser::GetMac( vector < string >& vMac )
{
    vMac.clear();
    char data[4096];
    ZeroMemory( data, 4096 );
     unsigned long  len = 4000;
    PIP_ADAPTER_INFO pinfo = ( PIP_ADAPTER_INFO ) data;

    DWORD ret = GetAdaptersInfo( pinfo, &len );
    if( ret != ERROR_SUCCESS )
        return;

    while ( pinfo ) {
    if( pinfo->Type == MIB_IF_TYPE_ETHERNET ) (
            // ignore software loopbacks and other strange things that might be present
        continue;
        char sbuf[20];
        string sret;
        for(int k = 0; k < 5; k++ ) {
            sprintf(sbuf,"%02X-",pinfo->Address[k]);
            sret += sbuf;
        }
        sprintf(sbuf,"%02X",pinfo->Address[5]);
            sret += sbuf;
        vMac.push_back( sret );
            }
        pinfo = pinfo->Next;
    }

}
3 голосов
/ 26 мая 2011

Я пытался сделать что-то подобное несколько лет назад и потерпел неудачу. Я попытался использовать комбинацию идентификаторов оборудования, которые я мог прочитать. Большинство CPU имеют CPUID, уникальный номер, который используется для уникальной идентификации и отслеживания их. Однако проблема в том, что не гарантируется, что каждый процессор будет иметь этот идентификатор. Фактически, когда я попробовал это, серия Intel Celeron не имела этого идентификатора. Некоторые материнские платы (в основном Intel) также поставляются с уникальным идентификатором, который вы можете использовать.

Здесь - ссылка на статью, в которой описано, как получить эту информацию.

Я также использовал любые / все MAC-идентификаторы в сочетании с CPU ID и MB ID в качестве начального числа для генерации уникального GUID. Чем больше идентификаторов оборудования вы используете в качестве начального числа, тем лучше это выполняется. Проблема заключается в том, что при обновлении любого из компонентов оборудования идентификатор изменяется, и ключ программного обеспечения становится недействительным.

Также имейте в виду, что виртуальные машины усложняют это еще больше. Я думаю, что вам лучше всего делать то, что делает Microsoft.

Microsoft использует аналогичный подход, когда берет аппаратный отпечаток компьютера, на котором установлена ​​ОС, и передает его вместе с ключом регистрации, чтобы активировать копию пакета ОС / Office. Если вы значительно модернизируете свое оборудование (я думаю, 4 аппаратных компонента), ключ изменится, и вам придется связаться с Microsoft и предоставить подтверждение для повторной проверки вашей копии Windows.

2 голосов
/ 26 мая 2011

Если вам нужно сгенерировать его только один раз, GUID будет уникальным для машины, которая его создала.Проблема в том, что вы будете получать разные значения каждый раз, когда генерируете их.Но если это один раз на машину, GUID будет работать.

Если он должен быть одинаковым для каждой машины и генерироваться несколько раз, MAC-адрес является универсальным идентификатором для машин (хотя вы можете иметьнесколько MAC на выбор).

1 голос
/ 26 мая 2011

Если бы такая вещь была простой и надежной, Microsoft давно бы нашла и запатентовала ее.

Были попытки защитить программное обеспечение некоторыми аппаратными средствами, в том числе поставка «1003 * ключа» с каждым лицензионным программным пакетом.Эй, дорогой новый клиент!Просто подключите ключ и запустите ваше новое программное обеспечение!

Было бунтом видеть, как Rube Goldberg состоит из трех или четырех ключей, подключенных один к другому и свисающих с параллельного порта, каждый из которых включает свой собственный пакет программного обеспечения,

0 голосов
/ 15 августа 2013

Может быть, этот метод поможет вам.http://www.codeproject.com/Articles/319181/Haephrati-Searching-for-a-reliable-Hardware-ID

0 голосов
/ 26 мая 2011

Одним из многих вариантов является использование идентификатора процессора.Лучше, чем Windows Registry или сетевая карта, например.Вы не хотите, чтобы пользователи беспокоили вас каждый раз, когда они меняют сетевую карту и т. Д. Я думаю, что проект cpuid можно использовать в качестве примера и отправной точки.

...